summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt6
-rw-r--r--api/system-current.txt6
-rw-r--r--api/test-current.txt6
-rw-r--r--cmds/screencap/screencap.cpp2
-rw-r--r--core/java/android/app/ActivityThread.java64
-rw-r--r--core/java/android/app/Application.java76
-rw-r--r--core/java/android/app/ContextImpl.java8
-rw-r--r--core/java/android/app/timezone/RulesState.java29
-rw-r--r--core/java/android/bluetooth/le/BluetoothLeScanner.java5
-rw-r--r--core/java/android/content/Context.java6
-rw-r--r--core/java/android/content/ContextWrapper.java6
-rw-r--r--core/java/android/hardware/radio/RadioManager.java4
-rw-r--r--core/java/android/hardware/radio/RadioMetadata.java6
-rw-r--r--core/java/android/hardware/radio/TunerAdapter.java2
-rw-r--r--core/java/android/net/ConnectivityManager.java4
-rw-r--r--core/java/android/os/INetworkManagementService.aidl6
-rw-r--r--core/java/android/text/StaticLayout.java30
-rw-r--r--core/java/android/widget/ListPopupWindow.java11
-rw-r--r--core/java/android/widget/TextView.java6
-rw-r--r--core/jni/android_media_AudioSystem.cpp10
-rw-r--r--core/jni/android_text_StaticLayout.cpp18
-rw-r--r--core/res/res/values-mcc302-mnc370/strings.xml25
-rw-r--r--core/res/res/values-mcc302-mnc720/strings.xml25
-rw-r--r--core/tests/coretests/src/android/app/timezone/RulesStateTest.java51
-rw-r--r--core/tests/coretests/src/android/text/StaticLayoutTest.java75
-rw-r--r--media/java/android/media/AudioFormat.java42
-rw-r--r--media/java/android/media/AudioRecordingConfiguration.java81
-rw-r--r--media/java/android/media/AudioSystem.java15
-rw-r--r--media/java/android/media/MediaRecorder.java34
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java8
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java49
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java2
-rw-r--r--packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java12
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java2
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java113
-rw-r--r--packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java293
-rw-r--r--packages/SystemUI/res/color/qs_background_dark.xml2
-rw-r--r--packages/SystemUI/res/drawable/pip_icon.xml25
-rw-r--r--packages/SystemUI/res/drawable/qs_background_primary.xml2
-rw-r--r--packages/SystemUI/res/layout/volume_dialog.xml7
-rw-r--r--packages/SystemUI/res/layout/volume_dialog_wrapped.xml11
-rw-r--r--packages/SystemUI/res/values/config.xml4
-rw-r--r--packages/SystemUI/res/values/dimens.xml8
-rw-r--r--packages/SystemUI/src/com/android/systemui/RoundedCorners.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java125
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java161
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java57
-rw-r--r--packages/SystemUI/tests/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java82
-rw-r--r--proto/src/metrics_constants.proto10
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java7
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java3
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/SaveUi.java1
-rw-r--r--services/core/java/com/android/server/LocationManagerService.java110
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java9
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java22
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java16
-rw-r--r--services/core/java/com/android/server/audio/RecordingActivityMonitor.java118
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java30
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java24
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java3
-rw-r--r--services/core/java/com/android/server/radio/RadioService.java5
-rw-r--r--services/core/java/com/android/server/wm/DockedStackDividerController.java3
-rw-r--r--services/core/java/com/android/server/wm/Session.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java91
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java4
-rw-r--r--services/core/jni/com_android_server_radio_RadioService.cpp6
-rw-r--r--services/core/jni/com_android_server_radio_Tuner.cpp2
-rw-r--r--services/net/java/android/net/ip/IpManager.java40
-rw-r--r--test-runner/src/android/test/mock/MockContext.java6
-rw-r--r--test-runner/tests/Android.mk7
-rw-r--r--test-runner/tests/src/android/test/TestCaseUtilTest.java4
-rw-r--r--test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java21
-rw-r--r--test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java1
-rw-r--r--test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java1
-rw-r--r--test-runner/tests/src/android/test/suitebuilder/examples/error/RunAsPartOfSeparateTest.java30
-rw-r--r--tools/aapt2/cmd/Optimize.cpp7
-rw-r--r--tools/aapt2/configuration/ConfigurationParser.cpp429
-rw-r--r--tools/aapt2/configuration/ConfigurationParser.h13
-rw-r--r--tools/aapt2/configuration/ConfigurationParser_test.cpp20
98 files changed, 1994 insertions, 910 deletions
diff --git a/api/current.txt b/api/current.txt
index d2c67adf491b..40cb282cb1c1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4208,6 +4208,12 @@ package android.app {
public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
ctor public Application();
+ method public android.app.Activity instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+ method public android.app.backup.BackupAgent instantiateBackupAgent(java.lang.ClassLoader, java.lang.String);
+ method public android.app.Instrumentation instantiateInstrumentation(java.lang.ClassLoader, java.lang.String);
+ method public android.content.ContentProvider instantiateProvider(java.lang.ClassLoader, java.lang.String);
+ method public android.content.BroadcastReceiver instantiateReceiver(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+ method public android.app.Service instantiateService(java.lang.ClassLoader, java.lang.String, android.content.Intent);
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onCreate();
method public void onLowMemory();
diff --git a/api/system-current.txt b/api/system-current.txt
index 648bb54ac711..3231b4d40dfe 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4363,6 +4363,12 @@ package android.app {
public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
ctor public Application();
+ method public android.app.Activity instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+ method public android.app.backup.BackupAgent instantiateBackupAgent(java.lang.ClassLoader, java.lang.String);
+ method public android.app.Instrumentation instantiateInstrumentation(java.lang.ClassLoader, java.lang.String);
+ method public android.content.ContentProvider instantiateProvider(java.lang.ClassLoader, java.lang.String);
+ method public android.content.BroadcastReceiver instantiateReceiver(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+ method public android.app.Service instantiateService(java.lang.ClassLoader, java.lang.String, android.content.Intent);
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onCreate();
method public void onLowMemory();
diff --git a/api/test-current.txt b/api/test-current.txt
index 2530d6849248..bc05da67c38f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4221,6 +4221,12 @@ package android.app {
public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
ctor public Application();
+ method public android.app.Activity instantiateActivity(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+ method public android.app.backup.BackupAgent instantiateBackupAgent(java.lang.ClassLoader, java.lang.String);
+ method public android.app.Instrumentation instantiateInstrumentation(java.lang.ClassLoader, java.lang.String);
+ method public android.content.ContentProvider instantiateProvider(java.lang.ClassLoader, java.lang.String);
+ method public android.content.BroadcastReceiver instantiateReceiver(java.lang.ClassLoader, java.lang.String, android.content.Intent);
+ method public android.app.Service instantiateService(java.lang.ClassLoader, java.lang.String, android.content.Intent);
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onCreate();
method public void onLowMemory();
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 71be63237739..23668786abee 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -253,5 +253,5 @@ int main(int argc, char** argv)
}
// b/36066697: Avoid running static destructors.
- _exit(1);
+ _exit(0);
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 905a3ee9d25b..f868d475fc7b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2678,8 +2678,14 @@ public final class ActivityThread {
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
- activity = mInstrumentation.newActivity(
- cl, component.getClassName(), r.intent);
+ if (appContext.getApplicationContext() instanceof Application) {
+ activity = ((Application) appContext.getApplicationContext())
+ .instantiateActivity(cl, component.getClassName(), r.intent);
+ }
+ if (activity == null) {
+ activity = mInstrumentation.newActivity(
+ cl, component.getClassName(), r.intent);
+ }
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
@@ -3204,7 +3210,8 @@ public final class ActivityThread {
data.intent.setExtrasClassLoader(cl);
data.intent.prepareToEnterProcess();
data.setExtrasClassLoader(cl);
- receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
+ receiver = instantiate(cl, component, data.intent, app,
+ Application::instantiateReceiver);
} catch (Exception e) {
if (DEBUG_BROADCAST) Slog.i(TAG,
"Finishing failed broadcast to " + data.intent.getComponent());
@@ -3292,12 +3299,13 @@ public final class ActivityThread {
} else {
try {
if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
+ ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
- agent = (BackupAgent) cl.loadClass(classname).newInstance();
+ agent = instantiate(cl, classname, context,
+ Application::instantiateBackupAgent);
// set up the agent's context
- ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(agent);
agent.attach(context);
@@ -3357,9 +3365,12 @@ public final class ActivityThread {
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
+ Application app = null;
try {
+ app = packageInfo.makeApplication(false, mInstrumentation);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
- service = (Service) cl.loadClass(data.info.name).newInstance();
+ service = instantiate(cl, data.info.name, data.intent, app,
+ Application::instantiateService);
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
@@ -3374,7 +3385,6 @@ public final class ActivityThread {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
- Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
service.onCreate();
@@ -5691,8 +5701,8 @@ public final class ActivityThread {
try {
final ClassLoader cl = instrContext.getClassLoader();
- mInstrumentation = (Instrumentation)
- cl.loadClass(data.instrumentationName.getClassName()).newInstance();
+ mInstrumentation = instantiate(cl, data.instrumentationName.getClassName(),
+ instrContext, Application::instantiateInstrumentation);
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
@@ -6237,8 +6247,8 @@ public final class ActivityThread {
try {
final java.lang.ClassLoader cl = c.getClassLoader();
- localProvider = (ContentProvider)cl.
- loadClass(info.name).newInstance();
+ localProvider = instantiate(cl, info.name, context,
+ Application::instantiateProvider);
provider = localProvider.getIContentProvider();
if (provider == null) {
Slog.e(TAG, "Failed to instantiate class " +
@@ -6437,6 +6447,38 @@ public final class ActivityThread {
}
}
+ private <T> T instantiate(ClassLoader cl, String className, Context c,
+ Instantiator<T> instantiator)
+ throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+ if (c.getApplicationContext() instanceof Application) {
+ T a = instantiator.instantiate((Application) c.getApplicationContext(),
+ cl, className);
+ if (a != null) return a;
+ }
+ return (T) cl.loadClass(className).newInstance();
+ }
+
+ private <T> T instantiate(ClassLoader cl, String className, Intent intent, Context c,
+ IntentInstantiator<T> instantiator)
+ throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+ if (c.getApplicationContext() instanceof Application) {
+ T a = instantiator.instantiate((Application) c.getApplicationContext(),
+ cl, className, intent);
+ if (a != null) return a;
+ }
+ return (T) cl.loadClass(className).newInstance();
+ }
+
+ private interface Instantiator<T> {
+ T instantiate(Application app, ClassLoader cl, String className)
+ throws ClassNotFoundException, IllegalAccessException, InstantiationException;
+ }
+
+ private interface IntentInstantiator<T> {
+ T instantiate(Application app, ClassLoader cl, String className, Intent intent)
+ throws ClassNotFoundException, IllegalAccessException, InstantiationException;
+ }
+
private static class EventLoggingReporter implements EventLogger.Reporter {
@Override
public void report (int code, Object... list) {
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 156df36a600c..cc23ec9023b6 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -16,17 +16,20 @@
package android.app;
-import java.util.ArrayList;
-
import android.annotation.CallSuper;
+import android.app.backup.BackupAgent;
+import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
+import android.content.ContentProvider;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
+import java.util.ArrayList;
+
/**
* Base class for maintaining global application state. You can provide your own
* implementation by creating a subclass and specifying the fully-qualified name
@@ -289,4 +292,73 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
}
}
}
+
+ /**
+ * Allows application to override the creation of activities. This can be used to
+ * perform things such as dependency injection or class loader changes to these
+ * classes. Return null to use the default creation flow.
+ * @param cl The default classloader to use for instantiation.
+ * @param className The class to be instantiated.
+ * @param intent Intent creating the class.
+ */
+ public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) {
+ return null;
+ }
+
+ /**
+ * Allows application to override the creation of receivers. This can be used to
+ * perform things such as dependency injection or class loader changes to these
+ * classes. Return null to use the default creation flow.
+ * @param cl The default classloader to use for instantiation.
+ * @param className The class to be instantiated.
+ * @param intent Intent creating the class.
+ */
+ public BroadcastReceiver instantiateReceiver(ClassLoader cl, String className, Intent intent) {
+ return null;
+ }
+
+ /**
+ * Allows application to override the creation of services. This can be used to
+ * perform things such as dependency injection or class loader changes to these
+ * classes. Return null to use the default creation flow.
+ * @param cl The default classloader to use for instantiation.
+ * @param className The class to be instantiated.
+ * @param intent Intent creating the class.
+ */
+ public Service instantiateService(ClassLoader cl, String className, Intent intent) {
+ return null;
+ }
+
+ /**
+ * Allows application to override the creation of providers. This can be used to
+ * perform things such as dependency injection or class loader changes to these
+ * classes. Return null to use the default creation flow.
+ * @param cl The default classloader to use for instantiation.
+ * @param className The class to be instantiated.
+ */
+ public ContentProvider instantiateProvider(ClassLoader cl, String className) {
+ return null;
+ }
+
+ /**
+ * Allows application to override the creation of backup agents. This can be used to
+ * perform things such as dependency injection or class loader changes to these
+ * classes. Return null to use the default creation flow.
+ * @param cl The default classloader to use for instantiation.
+ * @param className The class to be instantiated.
+ */
+ public BackupAgent instantiateBackupAgent(ClassLoader cl, String className) {
+ return null;
+ }
+
+ /**
+ * Allows application to override the creation of instrumentation. This can be used to
+ * perform things such as dependency injection or class loader changes to these
+ * classes. Return null to use the default creation flow.
+ * @param cl The default classloader to use for instantiation.
+ * @param className The class to be instantiated.
+ */
+ public Instrumentation instantiateInstrumentation(ClassLoader cl, String className) {
+ return null;
+ }
} \ No newline at end of file
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index a040520ffb9f..318c7ac31522 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2157,6 +2157,14 @@ class ContextImpl extends Context {
}
@Override
+ public boolean canLoadUnsafeResources() {
+ if (getPackageName().equals(getOpPackageName())) {
+ return true;
+ }
+ return (mFlags & Context.CONTEXT_IGNORE_SECURITY) != 0;
+ }
+
+ @Override
public Display getDisplay() {
if (mDisplay == null) {
return mResourcesManager.getAdjustedDisplay(Display.DEFAULT_DISPLAY,
diff --git a/core/java/android/app/timezone/RulesState.java b/core/java/android/app/timezone/RulesState.java
index 33f4e8060b3e..7d6ad2119fb7 100644
--- a/core/java/android/app/timezone/RulesState.java
+++ b/core/java/android/app/timezone/RulesState.java
@@ -174,29 +174,14 @@ public final class RulesState implements Parcelable {
}
/**
- * Returns true if the distro IANA rules version supplied is newer or the same as the version in
- * the system image data files.
+ * Returns true if the system image data files contain IANA rules data that are newer than the
+ * distro IANA rules version supplied, i.e. true when the version specified would be "worse"
+ * than the one that is in the system image. Returns false if the system image version is the
+ * same or older, i.e. false when the version specified would be "better" than the one that is
+ * in the system image.
*/
- public boolean isSystemVersionOlderThan(DistroRulesVersion distroRulesVersion) {
- return mSystemRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) < 0;
- }
-
- public boolean isDistroInstalled() {
- return mDistroStatus == DISTRO_STATUS_INSTALLED;
- }
-
- /**
- * Returns true if the rules version supplied is newer than the one currently installed. If
- * there is no installed distro this method throws IllegalStateException.
- */
- public boolean isInstalledDistroOlderThan(DistroRulesVersion distroRulesVersion) {
- if (mOperationInProgress) {
- throw new IllegalStateException("Distro state not known: operation in progress.");
- }
- if (!isDistroInstalled()) {
- throw new IllegalStateException("No distro installed.");
- }
- return mInstalledDistroRulesVersion.isOlderThan(distroRulesVersion);
+ public boolean isSystemVersionNewerThan(DistroRulesVersion distroRulesVersion) {
+ return mSystemRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) > 0;
}
public static final Parcelable.Creator<RulesState> CREATOR =
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index f3f0ae5cd959..1eac395bd06c 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -136,6 +136,11 @@ public final class BluetoothLeScanner {
* Start Bluetooth LE scan using a {@link PendingIntent}. The scan results will be delivered via
* the PendingIntent. Use this method of scanning if your process is not always running and it
* should be started when scan results are available.
+ * <p>
+ * When the PendingIntent is delivered, the Intent passed to the receiver or activity
+ * will contain one or more of the extras {@link #EXTRA_CALLBACK_TYPE},
+ * {@link #EXTRA_ERROR_CODE} and {@link #EXTRA_LIST_SCAN_RESULT} to indicate the result of
+ * the scan.
*
* @param filters Optional list of ScanFilters for finding exact BLE devices.
* @param settings Optional settings for the scan.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5929aca0a38f..ef6170359dda 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4681,6 +4681,12 @@ public abstract class Context {
public abstract boolean isCredentialProtectedStorage();
/**
+ * Returns true if the context can load unsafe resources, e.g. fonts.
+ * @hide
+ */
+ public abstract boolean canLoadUnsafeResources();
+
+ /**
* @hide
*/
public IBinder getActivityToken() {
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index c719c6474cf1..a9fd58bc950c 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -925,6 +925,12 @@ public class ContextWrapper extends Context {
return mBase.isCredentialProtectedStorage();
}
+ /** {@hide} */
+ @Override
+ public boolean canLoadUnsafeResources() {
+ return mBase.canLoadUnsafeResources();
+ }
+
/**
* @hide
*/
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index 434cf51bbefc..99bf25520458 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -1486,7 +1486,7 @@ public class RadioManager {
return nativeListModules(modules);
}
- Log.v(TAG, "Listing available tuners...");
+ Log.d(TAG, "Listing available tuners...");
List<ModuleProperties> returnedList;
try {
returnedList = mService.listModules();
@@ -1527,7 +1527,7 @@ public class RadioManager {
}
if (mService != null) {
- Log.d(TAG, "Opening tuner...");
+ Log.d(TAG, "Opening tuner " + moduleId + "...");
ITuner tuner;
ITunerCallback halCallback = new TunerCallbackAdapter(callback, handler);
diff --git a/core/java/android/hardware/radio/RadioMetadata.java b/core/java/android/hardware/radio/RadioMetadata.java
index d07b40759be7..07dd5dbe0e18 100644
--- a/core/java/android/hardware/radio/RadioMetadata.java
+++ b/core/java/android/hardware/radio/RadioMetadata.java
@@ -15,21 +15,16 @@
*/
package android.hardware.radio;
-import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
-import java.util.ArrayList;
import java.util.Set;
/**
@@ -540,7 +535,6 @@ public final class RadioMetadata implements Parcelable {
}
int putClockFromNative(int nativeKey, long utcEpochSeconds, int timezoneOffsetInMinutes) {
- Log.d(TAG, "putClockFromNative()");
String key = getKeyFromNativeKey(nativeKey);
if (!METADATA_KEYS_TYPE.containsKey(key) ||
METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_CLOCK) {
diff --git a/core/java/android/hardware/radio/TunerAdapter.java b/core/java/android/hardware/radio/TunerAdapter.java
index 710dc1021dd8..dbaca62e639f 100644
--- a/core/java/android/hardware/radio/TunerAdapter.java
+++ b/core/java/android/hardware/radio/TunerAdapter.java
@@ -43,7 +43,7 @@ class TunerAdapter extends RadioTuner {
public void close() {
synchronized (mTuner) {
if (mIsClosed) {
- Log.d(TAG, "Tuner is already closed");
+ Log.v(TAG, "Tuner is already closed");
return;
}
mIsClosed = true;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index f47807142376..511466ae01c3 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -599,7 +599,7 @@ public class ConnectivityManager {
/**
* @hide
*/
- public final static int REQUEST_ID_UNSET = 0;
+ public static final int REQUEST_ID_UNSET = 0;
/**
* Static unique request used as a tombstone for NetworkCallbacks that have been unregistered.
@@ -607,7 +607,7 @@ public class ConnectivityManager {
* registered and those that were already unregistered.
* @hide
*/
- private final static NetworkRequest ALREADY_UNREGISTERED =
+ private static final NetworkRequest ALREADY_UNREGISTERED =
new NetworkRequest.Builder().clearCapabilities().build();
/**
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index c34de1551ebf..92e78bc8d977 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -97,6 +97,12 @@ interface INetworkManagementService
void enableIpv6(String iface);
/**
+ * Set IPv6 autoconf address generation mode.
+ * This is a no-op if an unsupported mode is requested.
+ */
+ void setIPv6AddrGenMode(String iface, int mode);
+
+ /**
* Enables or enables IPv6 ND offload.
*/
void setInterfaceIpv6NdOffload(String iface, boolean enable);
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 74ff6dc0ec7f..a8c6aa6cbbbb 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -18,6 +18,7 @@ package android.text;
import android.annotation.Nullable;
import android.graphics.Paint;
+import android.os.LocaleList;
import android.text.style.LeadingMarginSpan;
import android.text.style.LeadingMarginSpan.LeadingMarginSpan2;
import android.text.style.LineHeightSpan;
@@ -333,6 +334,16 @@ public class StaticLayout extends Layout {
return this;
}
+ private long[] getHyphenators(LocaleList locales) {
+ final int length = locales.size();
+ final long[] result = new long[length];
+ for (int i = 0; i < length; i++) {
+ final Locale locale = locales.get(i);
+ result[i] = Hyphenator.get(locale).getNativePtr();
+ }
+ return result;
+ }
+
/**
* Measurement and break iteration is done in native code. The protocol for using
* the native code is as follows.
@@ -342,7 +353,7 @@ public class StaticLayout extends Layout {
* future).
*
* Then, for each run within the paragraph:
- * - setLocale (this must be done at least for the first run, optional afterwards)
+ * - setLocales (this must be done at least for the first run, optional afterwards)
* - one of the following, depending on the type of run:
* + addStyleRun (a text run, to be measured in native code)
* + addMeasuredRun (a run already measured in Java, passed into native code)
@@ -354,15 +365,15 @@ public class StaticLayout extends Layout {
* After all paragraphs, call finish() to release expensive buffers.
*/
- private void setLocale(Locale locale) {
- if (!locale.equals(mLocale)) {
- nSetLocale(mNativePtr, locale.toLanguageTag(),
- Hyphenator.get(locale).getNativePtr());
- mLocale = locale;
+ private void setLocales(LocaleList locales) {
+ if (!locales.equals(mLocales)) {
+ nSetLocales(mNativePtr, locales.toLanguageTags(), getHyphenators(locales));
+ mLocales = locales;
}
}
/* package */ float addStyleRun(TextPaint paint, int start, int end, boolean isRtl) {
+ setLocales(paint.getTextLocales());
return nAddStyleRun(mNativePtr, paint.getNativeInstance(), paint.mNativeTypeface,
start, end, isRtl);
}
@@ -425,7 +436,7 @@ public class StaticLayout extends Layout {
// This will go away and be subsumed by native builder code
MeasuredText mMeasuredText;
- Locale mLocale;
+ LocaleList mLocales;
private static final SynchronizedPool<Builder> sPool = new SynchronizedPool<Builder>(3);
}
@@ -594,7 +605,7 @@ public class StaticLayout extends Layout {
// store fontMetrics per span range
// must be a multiple of 4 (and > 0) (store top, bottom, ascent, and descent per range)
int[] fmCache = new int[4 * 4];
- b.setLocale(paint.getTextLocale()); // TODO: also respect LocaleSpan within the text
+ b.setLocales(paint.getTextLocales());
mLineCount = 0;
@@ -1308,7 +1319,8 @@ public class StaticLayout extends Layout {
/* package */ static native long nLoadHyphenator(ByteBuffer buf, int offset,
int minPrefix, int minSuffix);
- private static native void nSetLocale(long nativePtr, String locale, long nativeHyphenator);
+ private static native void nSetLocales(long nativePtr, String locales,
+ long[] nativeHyphenators);
private static native void nSetIndents(long nativePtr, int[] indents);
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 2e8faeec6f13..0d676153b288 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -25,6 +25,7 @@ import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
@@ -532,8 +533,14 @@ public class ListPopupWindow implements ShowableListMenu {
public void setHeight(int height) {
if (height < 0 && ViewGroup.LayoutParams.WRAP_CONTENT != height
&& ViewGroup.LayoutParams.MATCH_PARENT != height) {
- throw new IllegalArgumentException(
- "Invalid height. Must be a positive value, MATCH_PARENT, or WRAP_CONTENT.");
+ if (mContext.getApplicationInfo().targetSdkVersion
+ < Build.VERSION_CODES.O) {
+ Log.e(TAG, "Negative value " + height + " passed to ListPopupWindow#setHeight"
+ + " produces undefined results");
+ } else {
+ throw new IllegalArgumentException(
+ "Invalid height. Must be a positive value, MATCH_PARENT, or WRAP_CONTENT.");
+ }
}
mDropDownHeight = height;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 6b328ea01997..9a924890fcd7 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -913,7 +913,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
case com.android.internal.R.styleable.TextAppearance_fontFamily:
- if (!context.isRestricted()) {
+ if (!context.isRestricted() && context.canLoadUnsafeResources()) {
try {
fontTypeface = appearance.getFont(attr);
} catch (UnsupportedOperationException
@@ -1233,7 +1233,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
case com.android.internal.R.styleable.TextView_fontFamily:
- if (!context.isRestricted()) {
+ if (!context.isRestricted() && context.canLoadUnsafeResources()) {
try {
fontTypeface = a.getFont(attr);
} catch (UnsupportedOperationException | Resources.NotFoundException e) {
@@ -3417,7 +3417,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Typeface fontTypeface = null;
String fontFamily = null;
- if (!context.isRestricted()) {
+ if (!context.isRestricted() && context.canLoadUnsafeResources()) {
try {
fontTypeface = ta.getFont(R.styleable.TextAppearance_fontFamily);
} catch (UnsupportedOperationException | Resources.NotFoundException e) {
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 1779ada24aac..e8f6074051cf 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -396,7 +396,7 @@ android_media_AudioSystem_dyn_policy_callback(int event, String8 regId, int val)
}
static void
-android_media_AudioSystem_recording_callback(int event, audio_session_t session, int source,
+android_media_AudioSystem_recording_callback(int event, const record_client_info_t *clientInfo,
const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
audio_patch_handle_t patchHandle)
{
@@ -404,8 +404,8 @@ android_media_AudioSystem_recording_callback(int event, audio_session_t session,
if (env == NULL) {
return;
}
- if (clientConfig == NULL || deviceConfig == NULL) {
- ALOGE("Unexpected null client/device configurations in recording callback");
+ if (clientInfo == NULL || clientConfig == NULL || deviceConfig == NULL) {
+ ALOGE("Unexpected null client/device info or configurations in recording callback");
return;
}
@@ -433,7 +433,7 @@ android_media_AudioSystem_recording_callback(int event, audio_session_t session,
jclass clazz = env->FindClass(kClassPathName);
env->CallStaticVoidMethod(clazz,
gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative,
- event, session, source, recParamArray);
+ event, (jint) clientInfo->uid, clientInfo->session, clientInfo->source, recParamArray);
env->DeleteLocalRef(clazz);
env->DeleteLocalRef(recParamArray);
@@ -1930,7 +1930,7 @@ int register_android_media_AudioSystem(JNIEnv *env)
"dynamicPolicyCallbackFromNative", "(ILjava/lang/String;I)V");
gAudioPolicyEventHandlerMethods.postRecordConfigEventFromNative =
GetStaticMethodIDOrDie(env, env->FindClass(kClassPathName),
- "recordingCallbackFromNative", "(III[I)V");
+ "recordingCallbackFromNative", "(IIII[I)V");
jclass audioMixClass = FindClassOrDie(env, "android/media/audiopolicy/AudioMix");
gAudioMixClass = MakeGlobalRefOrDie(env, audioMixClass);
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 4a445d8705ca..d81bc2f05018 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -137,15 +137,19 @@ static jlong nLoadHyphenator(JNIEnv* env, jclass, jobject buffer, jint offset,
return reinterpret_cast<jlong>(hyphenator);
}
-static void nSetLocale(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleName,
- jlong nativeHyphenator) {
- ScopedIcuLocale icuLocale(env, javaLocaleName);
+static void nSetLocales(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleNames,
+ jlongArray nativeHyphenators) {
minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
- minikin::Hyphenator* hyphenator = reinterpret_cast<minikin::Hyphenator*>(nativeHyphenator);
- if (icuLocale.valid()) {
- b->setLocale(icuLocale.locale(), hyphenator);
+ ScopedUtfChars localeNames(env, javaLocaleNames);
+ ScopedLongArrayRO hyphArr(env, nativeHyphenators);
+ const size_t numLocales = hyphArr.size();
+ std::vector<minikin::Hyphenator*> hyphVec;
+ hyphVec.reserve(numLocales);
+ for (size_t i = 0; i < numLocales; i++) {
+ hyphVec.push_back(reinterpret_cast<minikin::Hyphenator*>(hyphArr[i]));
}
+ b->setLocales(localeNames.c_str(), hyphVec);
}
static void nSetIndents(JNIEnv* env, jclass, jlong nativePtr, jintArray indents) {
@@ -194,7 +198,7 @@ static const JNINativeMethod gMethods[] = {
{"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
{"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
{"nLoadHyphenator", "(Ljava/nio/ByteBuffer;III)J", (void*) nLoadHyphenator},
- {"nSetLocale", "(JLjava/lang/String;J)V", (void*) nSetLocale},
+ {"nSetLocales", "(JLjava/lang/String;[J)V", (void*) nSetLocales},
{"nSetupParagraph", "(J[CIFIF[IIIIZ)V", (void*) nSetupParagraph},
{"nSetIndents", "(J[I)V", (void*) nSetIndents},
{"nAddStyleRun", "(JJJIIZ)F", (void*) nAddStyleRun},
diff --git a/core/res/res/values-mcc302-mnc370/strings.xml b/core/res/res/values-mcc302-mnc370/strings.xml
new file mode 100644
index 000000000000..f5b8496f9a0b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc370/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Template for showing mobile network operator name while WFC is active -->
+ <string-array name="wfcSpnFormats">
+ <item>%s</item>
+ <item>%s Wi-Fi</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values-mcc302-mnc720/strings.xml b/core/res/res/values-mcc302-mnc720/strings.xml
new file mode 100644
index 000000000000..f5b8496f9a0b
--- /dev/null
+++ b/core/res/res/values-mcc302-mnc720/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Template for showing mobile network operator name while WFC is active -->
+ <string-array name="wfcSpnFormats">
+ <item>%s</item>
+ <item>%s Wi-Fi</item>
+ </string-array>
+</resources>
diff --git a/core/tests/coretests/src/android/app/timezone/RulesStateTest.java b/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
index a9357c9175ab..7f4819bf63a1 100644
--- a/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
+++ b/core/tests/coretests/src/android/app/timezone/RulesStateTest.java
@@ -107,7 +107,7 @@ public class RulesStateTest {
"2016a", formatVersion(1, 1), true /* operationInProgress */,
RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
- checkParcelableRoundTrip(rulesStateWithNulls);
+ checkParcelableRoundTrip(rulesStateWithUnknowns);
}
private static void checkParcelableRoundTrip(RulesState rulesState) {
@@ -121,55 +121,14 @@ public class RulesStateTest {
}
@Test
- public void isSystemVersionOlderThan() {
+ public void isSystemVersionNewerThan() {
RulesState rulesState = new RulesState(
"2016b", formatVersion(1, 1), false /* operationInProgress */,
RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
- assertFalse(rulesState.isSystemVersionOlderThan(rulesVersion("2016a", 1)));
- assertFalse(rulesState.isSystemVersionOlderThan(rulesVersion("2016b", 1)));
- assertTrue(rulesState.isSystemVersionOlderThan(rulesVersion("2016c", 1)));
- }
-
- @Test
- public void isInstalledDistroOlderThan() {
- RulesState operationInProgress = new RulesState(
- "2016b", formatVersion(1, 1), true /* operationInProgress */,
- RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
- RulesState.STAGED_OPERATION_UNKNOWN, null /* installedDistroRulesVersion */);
- try {
- operationInProgress.isInstalledDistroOlderThan(rulesVersion("2016b", 1));
- fail();
- } catch (IllegalStateException expected) {
- }
-
- RulesState nothingInstalled = new RulesState(
- "2016b", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
- RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
- try {
- nothingInstalled.isInstalledDistroOlderThan(rulesVersion("2016b", 1));
- fail();
- } catch (IllegalStateException expected) {
- }
-
- DistroRulesVersion installedVersion = rulesVersion("2016b", 3);
- RulesState rulesStateWithInstalledVersion = new RulesState(
- "2016b", formatVersion(1, 1), false /* operationInProgress */,
- RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
- RulesState.DISTRO_STATUS_INSTALLED, installedVersion);
-
- DistroRulesVersion olderRules = rulesVersion("2016a", 1);
- assertEquals(installedVersion.isOlderThan(olderRules),
- rulesStateWithInstalledVersion.isInstalledDistroOlderThan(olderRules));
-
- DistroRulesVersion sameRules = rulesVersion("2016b", 1);
- assertEquals(installedVersion.isOlderThan(sameRules),
- rulesStateWithInstalledVersion.isInstalledDistroOlderThan(sameRules));
-
- DistroRulesVersion newerRules = rulesVersion("2016c", 1);
- assertEquals(installedVersion.isOlderThan(newerRules),
- rulesStateWithInstalledVersion.isInstalledDistroOlderThan(newerRules));
+ assertTrue(rulesState.isSystemVersionNewerThan(rulesVersion("2016a", 1)));
+ assertFalse(rulesState.isSystemVersionNewerThan(rulesVersion("2016b", 1)));
+ assertFalse(rulesState.isSystemVersionNewerThan(rulesVersion("2016c", 1)));
}
private static void assertEqualsContract(RulesState one, RulesState two) {
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
index 74a6cc629937..fb60e38fcbf6 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -22,10 +22,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import android.graphics.Paint.FontMetricsInt;
+import android.os.LocaleList;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.text.Layout.Alignment;
import android.text.method.EditorState;
+import android.text.style.LocaleSpan;
import android.util.Log;
import org.junit.Before;
@@ -35,6 +37,7 @@ import org.junit.runner.RunWith;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
/**
* Tests StaticLayout vertical metrics behavior.
@@ -671,4 +674,76 @@ public class StaticLayoutTest {
assertEquals(testLabel, 4, layout.getOffsetToRightOf(5));
}
}
+
+ @Test
+ public void testLocaleSpanAffectsHyphenation() {
+ TextPaint paint = new TextPaint();
+ paint.setTextLocale(Locale.US);
+ // Private use language, with no hyphenation rules.
+ final Locale privateLocale = Locale.forLanguageTag("qaa");
+
+ final String longWord = "philanthropic";
+ final float wordWidth = paint.measureText(longWord);
+ // Wide enough that words get hyphenated by default.
+ final int paraWidth = Math.round(wordWidth * 1.8f);
+ final String sentence = longWord + " " + longWord + " " + longWord + " " + longWord + " "
+ + longWord + " " + longWord;
+
+ final int numEnglishLines = StaticLayout.Builder
+ .obtain(sentence, 0, sentence.length(), paint, paraWidth)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
+ .build()
+ .getLineCount();
+
+ {
+ final SpannableString text = new SpannableString(sentence);
+ text.setSpan(new LocaleSpan(privateLocale), 0, text.length(),
+ Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ final int numPrivateLocaleLines = StaticLayout.Builder
+ .obtain(text, 0, text.length(), paint, paraWidth)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
+ .build()
+ .getLineCount();
+
+ // Since the paragraph set to English gets hyphenated, the number of lines would be
+ // smaller than the number of lines when there is a span setting a language that
+ // doesn't get hyphenated.
+ assertTrue(numEnglishLines < numPrivateLocaleLines);
+ }
+ {
+ // Same as the above test, except that the locale span now uses a locale list starting
+ // with the private non-hyphenating locale.
+ final SpannableString text = new SpannableString(sentence);
+ final LocaleList locales = new LocaleList(privateLocale, Locale.US);
+ text.setSpan(new LocaleSpan(locales), 0, text.length(),
+ Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ final int numPrivateLocaleLines = StaticLayout.Builder
+ .obtain(text, 0, text.length(), paint, paraWidth)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
+ .build()
+ .getLineCount();
+
+ assertTrue(numEnglishLines < numPrivateLocaleLines);
+ }
+ {
+ final SpannableString text = new SpannableString(sentence);
+ // Apply the private LocaleSpan only to the first word, which is not getting hyphenated
+ // anyway.
+ text.setSpan(new LocaleSpan(privateLocale), 0, longWord.length(),
+ Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ final int numPrivateLocaleLines = StaticLayout.Builder
+ .obtain(text, 0, text.length(), paint, paraWidth)
+ .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)
+ .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)
+ .build()
+ .getLineCount();
+
+ // Since the first word is not hyphenated anyway (there's enough width), the LocaleSpan
+ // should not affect the layout.
+ assertEquals(numEnglishLines, numPrivateLocaleLines);
+ }
+ }
}
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 81cc93da2e6f..93fc3da54550 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -267,6 +267,42 @@ public final class AudioFormat implements Parcelable {
**/
public static final int ENCODING_DOLBY_TRUEHD = 14;
+ /** @hide */
+ public static String toLogFriendlyEncoding(int enc) {
+ switch(enc) {
+ case ENCODING_INVALID:
+ return "ENCODING_INVALID";
+ case ENCODING_PCM_16BIT:
+ return "ENCODING_PCM_16BIT";
+ case ENCODING_PCM_8BIT:
+ return "ENCODING_PCM_8BIT";
+ case ENCODING_PCM_FLOAT:
+ return "ENCODING_PCM_FLOAT";
+ case ENCODING_AC3:
+ return "ENCODING_AC3";
+ case ENCODING_E_AC3:
+ return "ENCODING_E_AC3";
+ case ENCODING_DTS:
+ return "ENCODING_DTS";
+ case ENCODING_DTS_HD:
+ return "ENCODING_DTS_HD";
+ case ENCODING_MP3:
+ return "ENCODING_MP3";
+ case ENCODING_AAC_LC:
+ return "ENCODING_AAC_LC";
+ case ENCODING_AAC_HE_V1:
+ return "ENCODING_AAC_HE_V1";
+ case ENCODING_AAC_HE_V2:
+ return "ENCODING_AAC_HE_V2";
+ case ENCODING_IEC61937:
+ return "ENCODING_IEC61937";
+ case ENCODING_DOLBY_TRUEHD:
+ return "ENCODING_DOLBY_TRUEHD";
+ default :
+ return "invalid encoding " + enc;
+ }
+ }
+
/** Invalid audio channel configuration */
/** @deprecated Use {@link #CHANNEL_INVALID} instead. */
@Deprecated public static final int CHANNEL_CONFIGURATION_INVALID = 0;
@@ -693,6 +729,12 @@ public final class AudioFormat implements Parcelable {
return mPropertySetMask;
}
+ /** @hide */
+ public String toLogFriendlyString() {
+ return String.format("%dch %dHz %s",
+ getChannelCount(), mSampleRate, toLogFriendlyEncoding(mEncoding));
+ }
+
/**
* Builder class for {@link AudioFormat} objects.
* Use this class to configure and create an AudioFormat instance. By setting format
diff --git a/media/java/android/media/AudioRecordingConfiguration.java b/media/java/android/media/AudioRecordingConfiguration.java
index 50dbd035b84d..984c5542cb7b 100644
--- a/media/java/android/media/AudioRecordingConfiguration.java
+++ b/media/java/android/media/AudioRecordingConfiguration.java
@@ -17,10 +17,12 @@
package android.media;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -52,18 +54,59 @@ public final class AudioRecordingConfiguration implements Parcelable {
private final AudioFormat mDeviceFormat;
private final AudioFormat mClientFormat;
+ @NonNull private final String mClientPackageName;
+ private final int mClientUid;
+
private final int mPatchHandle;
/**
* @hide
*/
- public AudioRecordingConfiguration(int session, int source, AudioFormat clientFormat,
- AudioFormat devFormat, int patchHandle) {
+ public AudioRecordingConfiguration(int uid, int session, int source, AudioFormat clientFormat,
+ AudioFormat devFormat, int patchHandle, String packageName) {
+ mClientUid = uid;
mSessionId = session;
mClientSource = source;
mClientFormat = clientFormat;
mDeviceFormat = devFormat;
mPatchHandle = patchHandle;
+ mClientPackageName = packageName;
+ }
+
+ /**
+ * @hide
+ * For AudioService dump
+ * @param pw
+ */
+ public void dump(PrintWriter pw) {
+ pw.println(" " + toLogFriendlyString(this));
+ }
+
+ /**
+ * @hide
+ */
+ public static String toLogFriendlyString(AudioRecordingConfiguration arc) {
+ return new String("session:" + arc.mSessionId
+ + " -- source:" + MediaRecorder.toLogFriendlyAudioSource(arc.mClientSource)
+ + " -- uid:" + arc.mClientUid
+ + " -- patch:" + arc.mPatchHandle
+ + " -- pack:" + arc.mClientPackageName
+ + " -- format client=" + arc.mClientFormat.toLogFriendlyString()
+ + ", dev=" + arc.mDeviceFormat.toLogFriendlyString());
+ }
+
+ // Note that this method is called server side, so no "privileged" information is ever sent
+ // to a client that is not supposed to have access to it.
+ /**
+ * @hide
+ * Creates a copy of the recording configuration that is stripped of any data enabling
+ * identification of which application it is associated with ("anonymized").
+ * @param in
+ */
+ public static AudioRecordingConfiguration anonymizedCopy(AudioRecordingConfiguration in) {
+ return new AudioRecordingConfiguration( /*anonymized uid*/ -1,
+ in.mSessionId, in.mClientSource, in.mClientFormat,
+ in.mDeviceFormat, in.mPatchHandle, "" /*empty package name*/);
}
// matches the sources that return false in MediaRecorder.isSystemOnlyAudioSource(source)
@@ -120,6 +163,30 @@ public final class AudioRecordingConfiguration implements Parcelable {
public AudioFormat getClientFormat() { return mClientFormat; }
/**
+ * @pending for SystemApi
+ * Returns the package name of the application performing the recording.
+ * Where there are multiple packages sharing the same user id through the "sharedUserId"
+ * mechanism, only the first one with that id will be returned
+ * (see {@link PackageManager#getPackagesForUid(int)}).
+ * <p>This information is only available if the caller has the
+ * {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING} permission.
+ * <br>When called without the permission, the result is an empty string.
+ * @return the package name
+ */
+ public String getClientPackageName() { return mClientPackageName; }
+
+ /**
+ * @pending for SystemApi
+ * Returns the user id of the application performing the recording.
+ * <p>This information is only available if the caller has the
+ * {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING}
+ * permission.
+ * <br>The result is -1 without the permission.
+ * @return the user id
+ */
+ public int getClientUid() { return mClientUid; }
+
+ /**
* Returns information about the audio input device used for this recording.
* @return the audio recording device or null if this information cannot be retrieved
*/
@@ -185,6 +252,8 @@ public final class AudioRecordingConfiguration implements Parcelable {
mClientFormat.writeToParcel(dest, 0);
mDeviceFormat.writeToParcel(dest, 0);
dest.writeInt(mPatchHandle);
+ dest.writeString(mClientPackageName);
+ dest.writeInt(mClientUid);
}
private AudioRecordingConfiguration(Parcel in) {
@@ -193,6 +262,8 @@ public final class AudioRecordingConfiguration implements Parcelable {
mClientFormat = AudioFormat.CREATOR.createFromParcel(in);
mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in);
mPatchHandle = in.readInt();
+ mClientPackageName = in.readString();
+ mClientUid = in.readInt();
}
@Override
@@ -202,10 +273,12 @@ public final class AudioRecordingConfiguration implements Parcelable {
AudioRecordingConfiguration that = (AudioRecordingConfiguration) o;
- return ((mSessionId == that.mSessionId)
+ return ((mClientUid == that.mClientUid)
+ && (mSessionId == that.mSessionId)
&& (mClientSource == that.mClientSource)
&& (mPatchHandle == that.mPatchHandle)
&& (mClientFormat.equals(that.mClientFormat))
- && (mDeviceFormat.equals(that.mDeviceFormat)));
+ && (mDeviceFormat.equals(that.mDeviceFormat))
+ && (mClientPackageName.equals(that.mClientPackageName)));
}
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 6ef3091dcc70..c7c2dd8aedcd 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -287,6 +287,7 @@ public class AudioSystem
/**
* Callback for recording activity notifications events
* @param event
+ * @param uid uid of the client app performing the recording
* @param session
* @param source
* @param recordingFormat an array of ints containing respectively the client and device
@@ -298,9 +299,10 @@ public class AudioSystem
* 4: device channel mask
* 5: device sample rate
* 6: patch handle
+ * @param packName package name of the client app performing the recording. NOT SUPPORTED
*/
- void onRecordingConfigurationChanged(int event, int session, int source,
- int[] recordingFormat);
+ void onRecordingConfigurationChanged(int event, int uid, int session, int source,
+ int[] recordingFormat, String packName);
}
private static AudioRecordingCallback sRecordingCallback;
@@ -318,17 +320,18 @@ public class AudioSystem
* @param session
* @param source
* @param recordingFormat see
- * {@link AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int[])} for
- * the description of the record format.
+ * {@link AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int, int[])}
+ * for the description of the record format.
*/
- private static void recordingCallbackFromNative(int event, int session, int source,
+ private static void recordingCallbackFromNative(int event, int uid, int session, int source,
int[] recordingFormat) {
AudioRecordingCallback cb = null;
synchronized (AudioSystem.class) {
cb = sRecordingCallback;
}
if (cb != null) {
- cb.onRecordingConfigurationChanged(event, session, source, recordingFormat);
+ // TODO receive package name from native
+ cb.onRecordingConfigurationChanged(event, uid, session, source, recordingFormat, "");
}
}
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 33a7c836dec8..59a124fa434f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -324,6 +324,40 @@ public class MediaRecorder
}
}
+ /** @hide */
+ public static final String toLogFriendlyAudioSource(int source) {
+ switch(source) {
+ case AudioSource.DEFAULT:
+ return "DEFAULT";
+ case AudioSource.MIC:
+ return "MIC";
+ case AudioSource.VOICE_UPLINK:
+ return "VOICE_UPLINK";
+ case AudioSource.VOICE_DOWNLINK:
+ return "VOICE_DOWNLINK";
+ case AudioSource.VOICE_CALL:
+ return "VOICE_CALL";
+ case AudioSource.CAMCORDER:
+ return "CAMCORDER";
+ case AudioSource.VOICE_RECOGNITION:
+ return "VOICE_RECOGNITION";
+ case AudioSource.VOICE_COMMUNICATION:
+ return "VOICE_COMMUNICATION";
+ case AudioSource.REMOTE_SUBMIX:
+ return "REMOTE_SUBMIX";
+ case AudioSource.UNPROCESSED:
+ return "UNPROCESSED";
+ case AudioSource.RADIO_TUNER:
+ return "RADIO_TUNER";
+ case AudioSource.HOTWORD:
+ return "HOTWORD";
+ case AudioSource.AUDIO_SOURCE_INVALID:
+ return "AUDIO_SOURCE_INVALID";
+ default:
+ return "unknown source " + source;
+ }
+ }
+
/**
* Defines the video source. These constants are used with
* {@link MediaRecorder#setVideoSource(int)}.
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
index 5a1e603e7fa2..f1d43bfe4096 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
@@ -51,6 +51,12 @@ public class Tile implements Parcelable {
public Icon icon;
/**
+ * Whether the icon can be tinted. This should be set to true for monochrome (single-color)
+ * icons that can be tinted to match the design.
+ */
+ public boolean isIconTintable;
+
+ /**
* Intent to launch when the preference is selected.
*/
public Intent intent;
@@ -126,6 +132,7 @@ public class Tile implements Parcelable {
dest.writeBundle(metaData);
dest.writeString(key);
dest.writeParcelable(remoteViews, flags);
+ dest.writeBoolean(isIconTintable);
}
public void readFromParcel(Parcel in) {
@@ -147,6 +154,7 @@ public class Tile implements Parcelable {
metaData = in.readBundle();
key = in.readString();
remoteViews = in.readParcelable(RemoteViews.class.getClassLoader());
+ isIconTintable = in.readBoolean();
}
Tile(Parcel in) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index 04a3d1f81561..9620a9153f80 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -133,15 +133,25 @@ public class TileUtils {
/**
* Name of the meta-data item that should be set in the AndroidManifest.xml
- * to specify the title that should be displayed for the preference.
+ * to specify whether the icon is tintable. This should be a boolean value {@code true} or
+ * {@code false}, set using {@code android:value}
*/
- @Deprecated
- public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+ public static final String META_DATA_PREFERENCE_ICON_TINTABLE =
+ "com.android.settings.icon_tintable";
/**
* Name of the meta-data item that should be set in the AndroidManifest.xml
* to specify the title that should be displayed for the preference.
+ *
+ * <p>Note: It is preferred to provide this value using {@code android:resource} with a string
+ * resource for localization.
+ */
+ public static final String META_DATA_PREFERENCE_TITLE = "com.android.settings.title";
+
+ /**
+ * @deprecated Use {@link #META_DATA_PREFERENCE_TITLE} with {@code android:resource}
*/
+ @Deprecated
public static final String META_DATA_PREFERENCE_TITLE_RES_ID =
"com.android.settings.title.resid";
@@ -309,12 +319,13 @@ public class TileUtils {
intent.setPackage(settingPkg);
}
getTilesForIntent(context, user, intent, addedCache, defaultCategory, outTiles,
- usePriority, true);
+ usePriority, true, true);
}
- public static void getTilesForIntent(Context context, UserHandle user, Intent intent,
+ public static void getTilesForIntent(
+ Context context, UserHandle user, Intent intent,
Map<Pair<String, String>, Tile> addedCache, String defaultCategory, List<Tile> outTiles,
- boolean usePriority, boolean checkCategory) {
+ boolean usePriority, boolean checkCategory, boolean forceTintExternalIcon) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
PackageManager.GET_META_DATA, user.getIdentifier());
@@ -350,7 +361,7 @@ public class TileUtils {
tile.priority = usePriority ? resolved.priority : 0;
tile.metaData = activityInfo.metaData;
updateTileData(context, tile, activityInfo, activityInfo.applicationInfo,
- pm, providerMap);
+ pm, providerMap, forceTintExternalIcon);
if (DEBUG) Log.d(LOG_TAG, "Adding tile " + tile.title);
addedCache.put(key, tile);
@@ -366,25 +377,40 @@ public class TileUtils {
private static boolean updateTileData(Context context, Tile tile,
ActivityInfo activityInfo, ApplicationInfo applicationInfo, PackageManager pm,
- Map<String, IContentProvider> providerMap) {
+ Map<String, IContentProvider> providerMap, boolean forceTintExternalIcon) {
if (applicationInfo.isSystemApp()) {
+ boolean forceTintIcon = false;
int icon = 0;
Pair<String, Integer> iconFromUri = null;
CharSequence title = null;
String summary = null;
String keyHint = null;
+ boolean isIconTintable = false;
RemoteViews remoteViews = null;
// Get the activity's meta-data
try {
- Resources res = pm.getResourcesForApplication(
- applicationInfo.packageName);
+ Resources res = pm.getResourcesForApplication(applicationInfo.packageName);
Bundle metaData = activityInfo.metaData;
+ if (forceTintExternalIcon
+ && !context.getPackageName().equals(applicationInfo.packageName)) {
+ isIconTintable = true;
+ forceTintIcon = true;
+ }
+
if (res != null && metaData != null) {
if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
icon = metaData.getInt(META_DATA_PREFERENCE_ICON);
}
+ if (metaData.containsKey(META_DATA_PREFERENCE_ICON_TINTABLE)) {
+ if (forceTintIcon) {
+ Log.w(LOG_TAG, "Ignoring icon tintable for " + activityInfo);
+ } else {
+ isIconTintable =
+ metaData.getBoolean(META_DATA_PREFERENCE_ICON_TINTABLE);
+ }
+ }
int resId = 0;
if (metaData.containsKey(META_DATA_PREFERENCE_TITLE_RES_ID)) {
resId = metaData.getInt(META_DATA_PREFERENCE_TITLE_RES_ID);
@@ -392,8 +418,6 @@ public class TileUtils {
title = res.getString(resId);
}
}
- // Fallback to legacy title extraction if we couldn't get the title through
- // res id.
if ((resId == 0) && metaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
if (metaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
@@ -457,6 +481,7 @@ public class TileUtils {
activityInfo.name);
// Suggest a key for this tile
tile.key = keyHint;
+ tile.isIconTintable = isIconTintable;
tile.remoteViews = remoteViews;
return true;
diff --git a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
index a28bece100eb..167ffe61e42b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/suggestions/SuggestionParser.java
@@ -208,7 +208,7 @@ public class SuggestionParser {
intent.setPackage(category.pkg);
}
TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
- mAddCache, null, suggestions, true, false);
+ mAddCache, null, suggestions, true, false, false);
filterSuggestions(suggestions, countBefore, isSmartSuggestionEnabled);
if (!category.multiple && suggestions.size() > (countBefore + 1)) {
// If there are too many, remove them all and only re-add the one with the highest
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
index a3345ee58b7d..0ec75ecee066 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/utils/ZoneGetterTest.java
@@ -36,6 +36,8 @@ import static junit.framework.Assert.assertTrue;
public class ZoneGetterTest {
private static final String TIME_ZONE_LONDON_ID = "Europe/London";
private static final String TIME_ZONE_LA_ID = "America/Los_Angeles";
+ private static final String TIME_ZONE_ALGIERS_ID = "Africa/Algiers";
+ private static final String TIME_ZONE_CEUTA_ID = "Africa/Ceuta";
private Locale mLocaleEnUs;
private Calendar mCalendar;
@@ -59,6 +61,16 @@ public class ZoneGetterTest {
}
@Test
+ public void getTimeZoneOffsetAndName_setAlgiers_returnCentralEuropeanStandardTime() {
+ testTimeZoneOffsetAndNameInner(TIME_ZONE_ALGIERS_ID, "Central European Standard Time");
+ }
+
+ @Test
+ public void getTimeZoneOffsetAndName_setCeuta_returnCentralEuropeanSummerTime() {
+ testTimeZoneOffsetAndNameInner(TIME_ZONE_CEUTA_ID, "Central European Summer Time");
+ }
+
+ @Test
public void getZonesList_checkTypes() {
final List<Map<String, Object>> zones =
ZoneGetter.getZonesList(InstrumentationRegistry.getContext());
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
index 22fd83c67667..31abecda9a39 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TestConfig.java
@@ -19,5 +19,5 @@ package com.android.settingslib;
public class TestConfig {
public static final int SDK_VERSION = 23;
public static final String MANIFEST_PATH =
- "frameworks/base/packages/SettingsLib/robotests/AndroidManifest.xml";
+ "frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml";
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 7cfb32d7bdb0..036441839b5b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -16,6 +16,19 @@
package com.android.settingslib.drawer;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.robolectric.RuntimeEnvironment.application;
+
import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -50,8 +63,9 @@ import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
import org.robolectric.internal.ShadowExtractor;
import java.util.ArrayList;
@@ -59,20 +73,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-
@RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH,
sdk = TestConfig.SDK_VERSION,
@@ -100,8 +100,11 @@ public class TileUtilsTest {
MockitoAnnotations.initMocks(this);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
- mContentResolver = spy(RuntimeEnvironment.application.getContentResolver());
+ when(mPackageManager.getApplicationInfo(eq("abc"), anyInt()))
+ .thenReturn(application.getApplicationInfo());
+ mContentResolver = spy(application.getContentResolver());
when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ when(mContext.getPackageName()).thenReturn("com.android.settings");
}
@Test
@@ -118,7 +121,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
assertThat(outTiles.get(0).category).isEqualTo(testCategory);
@@ -139,7 +142,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
assertThat(outTiles.get(0).key).isEqualTo(keyHint);
@@ -159,7 +162,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.isEmpty()).isTrue();
}
@@ -182,7 +185,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
SuggestionParser parser = new SuggestionParser(
@@ -255,7 +258,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
assertThat(outTiles.get(0).title).isEqualTo("my title");
@@ -279,10 +282,60 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
assertThat(outTiles.get(0).title).isEqualTo("my localized title");
+
+ // Icon should be tintable because the tile is not from settings package, and
+ // "forceTintExternalIcon" is set
+ assertThat(outTiles.get(0).isIconTintable).isTrue();
+ }
+
+ @Test
+ public void getTilesForIntent_shouldNotTintIconIfInSettingsPackage() {
+ Intent intent = new Intent();
+ Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+ List<Tile> outTiles = new ArrayList<>();
+ List<ResolveInfo> info = new ArrayList<>();
+ ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+ URI_GET_SUMMARY, null, 123);
+ resolveInfo.activityInfo.packageName = "com.android.settings";
+ resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
+ info.add(resolveInfo);
+
+ when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+ .thenReturn(info);
+
+ TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+ null /* defaultCategory */, outTiles, false /* usePriority */,
+ false /* checkCategory */, true /* forceTintExternalIcon */);
+
+ assertThat(outTiles.size()).isEqualTo(1);
+ assertThat(outTiles.get(0).isIconTintable).isFalse();
+ }
+
+ @Test
+ public void getTilesForIntent_shouldMarkIconTintableIfMetadataSet() {
+ Intent intent = new Intent();
+ Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
+ List<Tile> outTiles = new ArrayList<>();
+ List<ResolveInfo> info = new ArrayList<>();
+ ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
+ URI_GET_SUMMARY, null, 123);
+ resolveInfo.activityInfo.metaData
+ .putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
+ info.add(resolveInfo);
+
+ when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
+ .thenReturn(info);
+
+ TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
+ null /* defaultCategory */, outTiles, false /* usePriority */,
+ false /* checkCategory */, false /* forceTintExternalIcon */);
+
+ assertThat(outTiles.size()).isEqualTo(1);
+ assertThat(outTiles.get(0).isIconTintable).isTrue();
}
@Test
@@ -301,7 +354,7 @@ public class TileUtilsTest {
// Case 1: No provider associated with the uri specified.
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -319,7 +372,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
@@ -341,7 +394,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
}
@@ -362,7 +415,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
Tile tile = outTiles.get(0);
@@ -399,7 +452,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
Tile tile = outTiles.get(0);
@@ -437,7 +490,7 @@ public class TileUtilsTest {
TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
null /* defaultCategory */, outTiles, false /* usePriority */,
- false /* checkCategory */);
+ false /* checkCategory */, true /* forceTintExternalIcon */);
assertThat(outTiles.size()).isEqualTo(1);
Tile tile = outTiles.get(0);
@@ -484,7 +537,9 @@ public class TileUtilsTest {
if (summaryUri != null) {
info.activityInfo.metaData.putString("com.android.settings.summary_uri", summaryUri);
}
- if (title != null) {
+ if (titleResId != 0) {
+ info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
+ } else if (title != null) {
info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
}
if (titleResId != 0) {
diff --git a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
index 81bc83134b21..d9719f356f14 100644
--- a/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
+++ b/packages/SystemUI/colorextraction/src/com/google/android/colorextraction/types/Tonal.java
@@ -101,7 +101,7 @@ public class Tonal implements ExtractionType {
hsl[0] /= 360f;
// Find the palette that contains the closest color
- TonalPalette palette = findTonalPalette(hsl[0]);
+ TonalPalette palette = findTonalPalette(hsl[0], hsl[1]);
if (palette == null) {
Log.w(TAG, "Could not find a tonal palette!");
return false;
@@ -251,7 +251,13 @@ public class Tonal implements ExtractionType {
}
@Nullable
- private static TonalPalette findTonalPalette(float h) {
+ private static TonalPalette findTonalPalette(float h, float s) {
+ // Fallback to a grey palette if the color is too desaturated.
+ // This avoids hue shifts.
+ if (s < 0.05f) {
+ return GREY_PALETTE;
+ }
+
TonalPalette best = null;
float error = Float.POSITIVE_INFINITY;
@@ -327,271 +333,280 @@ public class Tonal implements ExtractionType {
// a best fit. Each palette is defined as 22 HSL colors
private static final TonalPalette[] TONAL_PALETTES = {
new TonalPalette(
- new float[]{0.991f, 0.9833333333333333f, 0f, 0f, 0f, 0.01134380453752181f,
- 0.015625000000000003f, 0.024193548387096798f, 0.027397260273972573f,
- 0.017543859649122865f},
- new float[]{1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.2f, 0.27450980392156865f, 0.34901960784313724f,
- 0.4235294117647059f, 0.5490196078431373f, 0.6254901960784314f,
- 0.6862745098039216f, 0.7568627450980392f, 0.8568627450980393f,
- 0.9254901960784314f}
+ new float[] {1f, 1f, 0.991f, 0.991f, 0.9833333333333333f, 0f, 0f, 0f,
+ 0.01134380453752181f, 0.015625000000000003f, 0.024193548387096798f,
+ 0.027397260273972573f, 0.017543859649122865f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f,
+ 1f},
+ new float[] {0.04f, 0.09f, 0.14f, 0.2f, 0.27450980392156865f,
+ 0.34901960784313724f, 0.4235294117647059f, 0.5490196078431373f,
+ 0.6254901960784314f, 0.6862745098039216f, 0.7568627450980392f,
+ 0.8568627450980393f, 0.9254901960784314f}
),
new TonalPalette(
- new float[]{0.6385767790262171f, 0.6301169590643275f, 0.6223958333333334f,
- 0.6151079136690647f, 0.6065400843881856f, 0.5986964618249534f,
- 0.5910746812386157f, 0.5833333333333334f, 0.5748031496062993f,
- 0.5582010582010583f},
- new float[]{1f, 1f, 0.9014084507042253f, 0.8128654970760234f,
- 0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f,
- 1f, 1f, 1f},
- new float[]{0.17450980392156862f, 0.2235294117647059f, 0.2784313725490196f,
- 0.3352941176470588f, 0.388235294117647f, 0.44901960784313727f,
- 0.5392156862745098f, 0.6509803921568628f, 0.7509803921568627f,
- 0.8764705882352941f}
+ new float[] {0.638f, 0.638f, 0.6385767790262171f, 0.6301169590643275f,
+ 0.6223958333333334f, 0.6151079136690647f, 0.6065400843881856f,
+ 0.5986964618249534f, 0.5910746812386157f, 0.5833333333333334f,
+ 0.5748031496062993f, 0.5582010582010583f},
+ new float[] {1f, 1f, 1f, 1f, 0.9014084507042253f, 0.8128654970760234f,
+ 0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f, 1f, 1f,
+ 1f},
+ new float[] {0.05f, 0.12f, 0.17450980392156862f, 0.2235294117647059f,
+ 0.2784313725490196f, 0.3352941176470588f, 0.388235294117647f,
+ 0.44901960784313727f, 0.5392156862745098f, 0.6509803921568628f,
+ 0.7509803921568627f, 0.8764705882352941f}
),
new TonalPalette(
- new float[]{0.5669934640522876f, 0.5748031496062993f,
+ new float[] {0.563f, 0.569f, 0.5666f, 0.5669934640522876f, 0.5748031496062993f,
0.5595238095238095f, 0.5473118279569893f, 0.5393258426966292f,
0.5315955766192734f, 0.524031007751938f, 0.5154711673699016f,
0.508080808080808f, 0.5f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f, 1f},
- new float[]{0.2f, 0.24901960784313726f, 0.27450980392156865f,
- 0.30392156862745096f, 0.34901960784313724f, 0.4137254901960784f,
- 0.47647058823529415f, 0.5352941176470588f, 0.6764705882352942f, 0.8f}
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f,
+ 1f},
+ new float[] {0.07f, 0.12f, 0.16f, 0.2f, 0.24901960784313726f,
+ 0.27450980392156865f, 0.30392156862745096f, 0.34901960784313724f,
+ 0.4137254901960784f, 0.47647058823529415f, 0.5352941176470588f,
+ 0.6764705882352942f, 0.8f}
),
new TonalPalette(
- new float[]{0.5082304526748972f, 0.5069444444444444f, 0.5f, 0.5f,
- 0.5f, 0.48724954462659376f, 0.4800347222222222f,
- 0.4755134281200632f, 0.4724409448818897f, 0.4671052631578947f},
- new float[]{1f, 0.8888888888888887f, 0.9242424242424242f, 1f, 1f,
- 0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f},
- new float[]{0.1588235294117647f, 0.21176470588235297f,
- 0.25882352941176473f, 0.3f, 0.34901960784313724f,
+ new float[] {0.508f, 0.511f, 0.508f, 0.508f, 0.5082304526748972f,
+ 0.5069444444444444f, 0.5f, 0.5f, 0.5f, 0.48724954462659376f,
+ 0.4800347222222222f, 0.4755134281200632f, 0.4724409448818897f,
+ 0.4671052631578947f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 0.8888888888888887f, 0.9242424242424242f, 1f,
+ 1f, 0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f},
+ new float[] {0.04f, 0.06f, 0.08f, 0.12f, 0.1588235294117647f,
+ 0.21176470588235297f, 0.25882352941176473f, 0.3f, 0.34901960784313724f,
0.44117647058823534f, 0.5215686274509804f, 0.5862745098039216f,
0.7509803921568627f, 0.8509803921568627f}
),
new TonalPalette(
- new float[]{0.3333333333333333f, 0.3333333333333333f,
+ new float[] {0.333f, 0.333f, 0.333f, 0.3333333333333333f, 0.3333333333333333f,
0.34006734006734f, 0.34006734006734f, 0.34006734006734f,
0.34259259259259256f, 0.3475783475783476f, 0.34767025089605735f,
0.3467741935483871f, 0.3703703703703704f},
- new float[]{0.6703296703296703f, 0.728813559322034f,
+ new float[] {0.70f, 0.72f, 0.69f, 0.6703296703296703f, 0.728813559322034f,
0.5657142857142856f, 0.5076923076923077f, 0.3944223107569721f,
0.6206896551724138f, 0.8931297709923666f, 1f, 1f, 1f},
- new float[]{0.1784313725490196f, 0.23137254901960785f,
+ new float[] {0.05f, 0.08f, 0.1784313725490196f, 0.23137254901960785f,
0.3431372549019608f, 0.38235294117647056f, 0.49215686274509807f,
0.6588235294117647f, 0.7431372549019608f, 0.8176470588235294f,
0.8784313725490196f, 0.9294117647058824f}
),
new TonalPalette(
- new float[]{0.162280701754386f, 0.15032679738562088f,
+ new float[] {0.161f, 0.163f, 0.163f, 0.162280701754386f, 0.15032679738562088f,
0.15879265091863518f, 0.16236559139784948f, 0.17443868739205526f,
- 0.17824074074074076f, 0.18674698795180725f,
- 0.18692449355432778f, 0.1946778711484594f, 0.18604651162790695f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.14901960784313725f, 0.2f, 0.24901960784313726f,
- 0.30392156862745096f, 0.3784313725490196f, 0.4235294117647059f,
- 0.48823529411764705f, 0.6450980392156863f, 0.7666666666666666f,
- 0.8313725490196078f}
+ 0.17824074074074076f, 0.18674698795180725f, 0.18692449355432778f,
+ 0.1946778711484594f, 0.18604651162790695f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+ new float[] {0.05f, 0.08f, 0.11f, 0.14901960784313725f, 0.2f,
+ 0.24901960784313726f, 0.30392156862745096f, 0.3784313725490196f,
+ 0.4235294117647059f, 0.48823529411764705f, 0.6450980392156863f,
+ 0.7666666666666666f, 0.8313725490196078f}
),
new TonalPalette(
- new float[]{0.10619469026548674f, 0.11924686192468618f,
- 0.13046448087431692f, 0.14248366013071895f, 0.1506024096385542f,
- 0.16220238095238093f, 0.16666666666666666f,
+ new float[] {0.108f, 0.105f, 0.105f, 0.105f, 0.10619469026548674f,
+ 0.11924686192468618f, 0.13046448087431692f, 0.14248366013071895f,
+ 0.1506024096385542f, 0.16220238095238093f, 0.16666666666666666f,
0.16666666666666666f, 0.162280701754386f, 0.15686274509803924f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.44313725490196076f, 0.46862745098039216f,
- 0.47843137254901963f, 0.5f, 0.5117647058823529f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+ new float[] {0.17f, 0.22f, 0.28f, 0.35f, 0.44313725490196076f,
+ 0.46862745098039216f, 0.47843137254901963f, 0.5f, 0.5117647058823529f,
0.5607843137254902f, 0.6509803921568628f, 0.7509803921568627f,
0.8509803921568627f, 0.9f}
),
new TonalPalette(
- new float[]{0.03561253561253561f, 0.05098039215686275f,
- 0.07516339869281045f, 0.09477124183006536f, 0.1150326797385621f,
- 0.134640522875817f, 0.14640522875816991f, 0.1582397003745319f,
- 0.15773809523809523f, 0.15359477124183002f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.4588235294117647f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
- 0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f}
+ new float[] {0.036f, 0.036f, 0.036f, 0.036f, 0.03561253561253561f,
+ 0.05098039215686275f, 0.07516339869281045f, 0.09477124183006536f,
+ 0.1150326797385621f, 0.134640522875817f, 0.14640522875816991f,
+ 0.1582397003745319f, 0.15773809523809523f, 0.15359477124183002f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+ new float[] {0.19f, 0.26f, 0.34f, 0.39f, 0.4588235294117647f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f}
),
new TonalPalette(
- new float[]{0.9596491228070175f, 0.9593837535014005f,
+ new float[] {0.955f, 0.961f, 0.958f, 0.9596491228070175f, 0.9593837535014005f,
0.9514767932489452f, 0.943859649122807f, 0.9396825396825397f,
0.9395424836601307f, 0.9393939393939394f, 0.9362745098039216f,
0.9754098360655739f, 0.9824561403508771f},
- new float[]{0.84070796460177f, 0.8206896551724138f,
+ new float[] {0.87f, 0.85f, 0.85f, 0.84070796460177f, 0.8206896551724138f,
0.7979797979797981f, 0.7661290322580644f, 0.9051724137931036f,
1f, 1f, 1f, 1f, 1f},
- new float[]{0.22156862745098038f, 0.2843137254901961f,
+ new float[] {0.06f, 0.11f, 0.16f, 0.22156862745098038f, 0.2843137254901961f,
0.388235294117647f, 0.48627450980392156f, 0.5450980392156863f,
0.6f, 0.6764705882352942f, 0.8f, 0.8803921568627451f,
0.9254901960784314f}
),
new TonalPalette(
- new float[]{0.841025641025641f, 0.8333333333333334f,
+ new float[] {0.866f, 0.855f, 0.841025641025641f, 0.8333333333333334f,
0.8285256410256411f, 0.821522309711286f, 0.8083333333333333f,
0.8046594982078853f, 0.8005822416302766f, 0.7842377260981912f,
0.7771084337349398f, 0.7747747747747749f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f,
0.737142857142857f, 0.6434108527131781f, 0.46835443037974644f},
- new float[]{0.12745098039215685f, 0.15490196078431373f,
+ new float[] {0.05f, 0.08f, 0.12745098039215685f, 0.15490196078431373f,
0.20392156862745098f, 0.24901960784313726f, 0.3137254901960784f,
- 0.36470588235294116f, 0.44901960784313727f,
- 0.6568627450980392f, 0.7470588235294118f, 0.8450980392156863f}
+ 0.36470588235294116f, 0.44901960784313727f, 0.6568627450980392f,
+ 0.7470588235294118f, 0.8450980392156863f}
),
new TonalPalette(
- new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
- new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
- new float[]{0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
- 0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
- 0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f}
- ),
- new TonalPalette(
- new float[]{0.955952380952381f, 0.9681069958847737f,
- 0.9760479041916167f, 0.9873563218390804f, 0f, 0f,
+ new float[] {0.925f, 0.93f, 0.938f, 0.947f, 0.955952380952381f,
+ 0.9681069958847737f, 0.9760479041916167f, 0.9873563218390804f, 0f, 0f,
0.009057971014492771f, 0.026748971193415648f,
0.041666666666666616f, 0.05303030303030304f},
- new float[]{1f, 0.8350515463917526f, 0.6929460580912863f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 0.8350515463917526f, 0.6929460580912863f,
0.6387665198237885f, 0.6914893617021276f, 0.7583892617449666f,
0.8070175438596495f, 0.9310344827586209f, 1f, 1f},
- new float[]{0.27450980392156865f, 0.3803921568627451f,
- 0.4725490196078432f, 0.5549019607843138f, 0.6313725490196078f,
- 0.707843137254902f, 0.7764705882352941f, 0.8294117647058823f,
- 0.9058823529411765f, 0.9568627450980391f}
+ new float[] {0.10f, 0.13f, 0.17f, 0.2f, 0.27450980392156865f,
+ 0.3803921568627451f, 0.4725490196078432f, 0.5549019607843138f,
+ 0.6313725490196078f, 0.707843137254902f, 0.7764705882352941f,
+ 0.8294117647058823f, 0.9058823529411765f, 0.9568627450980391f}
),
new TonalPalette(
- new float[]{0.7514619883040936f, 0.7679738562091503f,
+ new float[] {0.733f, 0.736f, 0.744f, 0.7514619883040936f, 0.7679738562091503f,
0.7802083333333333f, 0.7844311377245509f, 0.796875f,
0.8165618448637316f, 0.8487179487179487f, 0.8582375478927203f,
0.8562091503267975f, 0.8666666666666667f},
- new float[]{1f, 1f, 0.8163265306122449f, 0.6653386454183268f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 0.8163265306122449f, 0.6653386454183268f,
0.7547169811320753f, 0.929824561403509f, 0.9558823529411766f,
0.9560439560439562f, 1f, 1f},
- new float[]{0.2235294117647059f, 0.3f, 0.38431372549019605f,
- 0.492156862745098f, 0.5843137254901961f, 0.6647058823529411f,
- 0.7333333333333334f, 0.8215686274509804f, 0.9f,
+ new float[] {0.07f, 0.12f, 0.17f, 0.2235294117647059f, 0.3f,
+ 0.38431372549019605f, 0.492156862745098f, 0.5843137254901961f,
+ 0.6647058823529411f, 0.7333333333333334f, 0.8215686274509804f, 0.9f,
0.9411764705882353f}
),
new TonalPalette(
- new float[]{0.6666666666666666f, 0.6666666666666666f,
+ new float[] {0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
0.6666666666666666f, 0.6666666666666666f},
- new float[]{0.24590163934426232f, 0.17880794701986752f,
+ new float[] {0.25f, 0.24590163934426232f, 0.17880794701986752f,
0.14606741573033713f, 0.13761467889908252f, 0.14893617021276592f,
- 0.16756756756756758f, 0.20312500000000017f,
- 0.26086956521739135f, 0.29999999999999966f, 0.5000000000000004f},
- new float[]{0.2392156862745098f, 0.296078431372549f,
+ 0.16756756756756758f, 0.20312500000000017f, 0.26086956521739135f,
+ 0.29999999999999966f, 0.5000000000000004f},
+ new float[] {0.18f, 0.2392156862745098f, 0.296078431372549f,
0.34901960784313724f, 0.4274509803921569f, 0.5392156862745098f,
0.6372549019607843f, 0.7490196078431373f, 0.8196078431372549f,
0.8823529411764706f, 0.9372549019607843f}
),
new TonalPalette(
- new float[]{0.9678571428571429f, 0.9944812362030905f, 0f, 0f,
+ new float[] {0.938f, 0.944f, 0.952f, 0.961f, 0.9678571428571429f,
+ 0.9944812362030905f, 0f, 0f,
0.0047348484848484815f, 0.00316455696202532f, 0f,
0.9980392156862745f, 0.9814814814814816f, 0.9722222222222221f},
- new float[]{1f, 0.7023255813953488f, 0.6638655462184874f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 0.7023255813953488f, 0.6638655462184874f,
0.6521739130434782f, 0.7719298245614035f, 0.8315789473684211f,
0.6867469879518071f, 0.7264957264957265f, 0.8181818181818182f,
0.8181818181818189f},
- new float[]{0.27450980392156865f, 0.4215686274509804f,
+ new float[] {0.08f, 0.13f, 0.18f, 0.23f, 0.27450980392156865f,
+ 0.4215686274509804f,
0.4666666666666667f, 0.503921568627451f, 0.5529411764705883f,
0.6274509803921569f, 0.6745098039215687f, 0.7705882352941176f,
0.892156862745098f, 0.9568627450980391f}
),
new TonalPalette(
- new float[]{0.9052287581699346f, 0.9112021857923498f, 0.9270152505446624f,
- 0.9343137254901961f, 0.9391534391534391f, 0.9437984496124031f,
- 0.943661971830986f, 0.9438943894389439f, 0.9426229508196722f,
- 0.9444444444444444f},
- new float[]{1f, 0.8133333333333332f, 0.7927461139896375f, 0.7798165137614679f,
- 0.7777777777777779f, 0.8190476190476191f, 0.8255813953488372f,
- 0.8211382113821142f, 0.8133333333333336f, 0.8000000000000006f},
- new float[]{0.2f, 0.29411764705882354f, 0.3784313725490196f,
- 0.42745098039215684f, 0.4764705882352941f, 0.5882352941176471f,
- 0.6627450980392157f, 0.7588235294117647f, 0.8529411764705882f,
- 0.9411764705882353f}
+ new float[] {0.88f, 0.888f, 0.897f, 0.9052287581699346f, 0.9112021857923498f,
+ 0.9270152505446624f, 0.9343137254901961f, 0.9391534391534391f,
+ 0.9437984496124031f, 0.943661971830986f, 0.9438943894389439f,
+ 0.9426229508196722f, 0.9444444444444444f},
+ new float[] {1f, 1f, 1f, 1f, 0.8133333333333332f, 0.7927461139896375f,
+ 0.7798165137614679f, 0.7777777777777779f, 0.8190476190476191f,
+ 0.8255813953488372f, 0.8211382113821142f, 0.8133333333333336f,
+ 0.8000000000000006f},
+ new float[] {0.08f, 0.12f, 0.16f, 0.2f, 0.29411764705882354f,
+ 0.3784313725490196f, 0.42745098039215684f, 0.4764705882352941f,
+ 0.5882352941176471f, 0.6627450980392157f, 0.7588235294117647f,
+ 0.8529411764705882f, 0.9411764705882353f}
),
new TonalPalette(
- new float[]{0.6884057971014492f, 0.6974789915966387f, 0.7079889807162534f,
- 0.7154471544715447f, 0.7217741935483872f, 0.7274143302180687f,
- 0.7272727272727273f, 0.7258064516129031f, 0.7252252252252251f,
- 0.7333333333333333f},
- new float[]{0.8214285714285715f, 0.6878612716763006f, 0.6080402010050251f,
- 0.5774647887323943f, 0.5391304347826086f, 0.46724890829694316f,
- 0.4680851063829788f, 0.462686567164179f, 0.45679012345678977f,
- 0.4545454545454551f},
- new float[]{0.2196078431372549f, 0.33921568627450976f, 0.39019607843137255f,
- 0.4176470588235294f, 0.45098039215686275f,
+ new float[] {0.669f, 0.680f, 0.6884057971014492f, 0.6974789915966387f,
+ 0.7079889807162534f, 0.7154471544715447f, 0.7217741935483872f,
+ 0.7274143302180687f, 0.7272727272727273f, 0.7258064516129031f,
+ 0.7252252252252251f, 0.7333333333333333f},
+ new float[] {0.81f, 0.81f, 0.8214285714285715f, 0.6878612716763006f,
+ 0.6080402010050251f, 0.5774647887323943f, 0.5391304347826086f,
+ 0.46724890829694316f, 0.4680851063829788f, 0.462686567164179f,
+ 0.45679012345678977f, 0.4545454545454551f},
+ new float[] {0.12f, 0.16f, 0.2196078431372549f, 0.33921568627450976f,
+ 0.39019607843137255f, 0.4176470588235294f, 0.45098039215686275f,
0.5509803921568628f, 0.6313725490196078f, 0.7372549019607844f,
0.8411764705882353f, 0.9352941176470588f}
),
new TonalPalette(
- new float[]{0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f,
+ new float[] {0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f,
0.6441441441441442f, 0.6432748538011696f, 0.6416666666666667f,
0.6402439024390243f, 0.6412429378531074f, 0.6435185185185186f,
0.6428571428571429f},
- new float[]{0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f,
+ new float[] {0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f,
0.5362318840579711f, 0.5f, 0.4424778761061947f, 0.44086021505376327f,
- 0.44360902255639095f,
- 0.4499999999999997f, 0.4375000000000006f},
- new float[]{0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f,
+ 0.44360902255639095f, 0.4499999999999997f, 0.4375000000000006f},
+ new float[] {0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f,
0.40588235294117647f, 0.44705882352941173f,
0.5568627450980392f, 0.6352941176470588f, 0.7392156862745098f,
0.8431372549019608f, 0.9372549019607843f}
),
new TonalPalette(
- new float[]{0.46732026143790845f, 0.4718614718614719f, 0.4793650793650794f,
- 0.48071625344352614f, 0.4829683698296837f, 0.484375f,
- 0.4841269841269842f, 0.48444444444444457f, 0.48518518518518516f,
- 0.4907407407407408f},
- new float[]{1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f,
- 0.41899441340782106f, 0.4128440366972478f,
- 0.4090909090909088f},
- new float[]{0.1f, 0.15098039215686274f, 0.20588235294117646f,
+ new float[] {0.469f, 0.46732026143790845f, 0.4718614718614719f,
+ 0.4793650793650794f, 0.48071625344352614f, 0.4829683698296837f,
+ 0.484375f, 0.4841269841269842f, 0.48444444444444457f,
+ 0.48518518518518516f, 0.4907407407407408f},
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f,
+ 0.41899441340782106f, 0.4128440366972478f, 0.4090909090909088f},
+ new float[] {0.07f, 0.1f, 0.15098039215686274f, 0.20588235294117646f,
0.2372549019607843f, 0.26862745098039215f, 0.4f, 0.5078431372549019f,
0.6490196078431372f, 0.7862745098039216f, 0.9137254901960784f}
),
new TonalPalette(
- new float[]{0.5444444444444444f, 0.5555555555555556f, 0.5555555555555556f,
- 0.553763440860215f, 0.5526315789473684f, 0.5555555555555556f,
- 0.5555555555555555f, 0.5555555555555556f, 0.5512820512820514f,
- 0.5666666666666667f},
- new float[]{0.24590163934426232f, 0.19148936170212766f, 0.1791044776119403f,
- 0.18343195266272191f, 0.18446601941747576f,
+ new float[] {0.542f, 0.5444444444444444f, 0.5555555555555556f,
+ 0.5555555555555556f, 0.553763440860215f, 0.5526315789473684f,
+ 0.5555555555555556f, 0.5555555555555555f, 0.5555555555555556f,
+ 0.5512820512820514f, 0.5666666666666667f},
+ new float[] {0.25f, 0.24590163934426232f, 0.19148936170212766f,
+ 0.1791044776119403f, 0.18343195266272191f, 0.18446601941747576f,
0.1538461538461539f, 0.15625000000000003f, 0.15328467153284678f,
0.15662650602409653f, 0.151515151515151f},
- new float[]{0.1196078431372549f, 0.1843137254901961f, 0.2627450980392157f,
+ new float[] {0.05f, 0.1196078431372549f, 0.1843137254901961f,
+ 0.2627450980392157f,
0.33137254901960783f, 0.403921568627451f, 0.5411764705882354f,
0.6235294117647059f, 0.7313725490196079f, 0.8372549019607843f,
0.9352941176470588f}
),
new TonalPalette(
- new float[]{0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f,
+ new float[] {0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f,
0.03947368421052631f, 0.04166666666666668f,
0.043650793650793655f, 0.04411764705882352f, 0.04166666666666652f,
0.04444444444444459f, 0.05555555555555529f},
- new float[]{0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f,
+ new float[] {0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f,
0.25675675675675674f, 0.2528735632183908f, 0.17500000000000002f,
0.15315315315315312f, 0.15189873417721522f,
0.15789473684210534f, 0.15789473684210542f},
- new float[]{0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f,
+ new float[] {0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f,
0.2901960784313725f, 0.3411764705882353f, 0.47058823529411764f,
0.5647058823529412f, 0.6901960784313725f, 0.8137254901960784f,
0.9254901960784314f}
),
new TonalPalette(
- new float[]{0.050884955752212385f, 0.07254901960784313f, 0.0934640522875817f,
+ new float[] {0.027f, 0.03f, 0.038f, 0.044f, 0.050884955752212385f,
+ 0.07254901960784313f, 0.0934640522875817f,
0.10457516339869281f, 0.11699346405228758f,
0.1255813953488372f, 0.1268939393939394f, 0.12533333333333332f,
0.12500000000000003f, 0.12777777777777777f},
- new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
- new float[]{0.44313725490196076f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5784313725490196f,
+ new float[] {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+ new float[] {0.25f, 0.3f, 0.35f, 0.4f, 0.44313725490196076f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5784313725490196f,
0.6549019607843137f, 0.7549019607843137f, 0.8509803921568627f,
0.9411764705882353f}
)
};
+ private static final TonalPalette GREY_PALETTE = new TonalPalette(
+ new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+ new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+ new float[]{0.08f, 0.11f, 0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
+ 0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
+ 0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f}
+ );
+
@SuppressWarnings("WeakerAccess")
@VisibleForTesting
static final ColorRange[] BLACKLISTED_COLORS = new ColorRange[] {
diff --git a/packages/SystemUI/res/color/qs_background_dark.xml b/packages/SystemUI/res/color/qs_background_dark.xml
index 1aa732f43286..62e495974623 100644
--- a/packages/SystemUI/res/color/qs_background_dark.xml
+++ b/packages/SystemUI/res/color/qs_background_dark.xml
@@ -16,5 +16,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.93"
- android:color="?android:attr/colorPrimaryDark"/>
+ android:color="?android:attr/colorBackgroundFloating"/>
</selector>
diff --git a/packages/SystemUI/res/drawable/pip_icon.xml b/packages/SystemUI/res/drawable/pip_icon.xml
new file mode 100644
index 000000000000..bd92ccd2e6e3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/pip_icon.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="36dp"
+ android:height="36dp"
+ android:viewportWidth="25"
+ android:viewportHeight="25">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M19,7h-8v6h8L19,7zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,1.98 2,1.98h18c1.1,0 2,-0.88 2,-1.98L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.98h18v14.03z"/>
+</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
index 416583013e64..03bba53946da 100644
--- a/packages/SystemUI/res/drawable/qs_background_primary.xml
+++ b/packages/SystemUI/res/drawable/qs_background_primary.xml
@@ -15,6 +15,6 @@
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android">
<shape>
- <solid android:color="?android:attr/colorBackgroundFloating"/>
+ <solid android:color="@color/qs_background_dark"/>
</shape>
</inset>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 90761994cde6..18ffd0fac417 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -16,12 +16,12 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/volume_dialog"
- android:layout_width="@dimen/volume_dialog_panel_width"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
- android:layout_gravity="center_vertical|end"
+ android:background="@drawable/volume_dialog_background"
android:paddingTop="@dimen/volume_dialog_padding_top"
- android:translationZ="8dp" >
+ android:translationZ="4dp" >
<LinearLayout
android:id="@+id/volume_dialog_content"
@@ -57,7 +57,6 @@
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
- android:visibility="gone"
android:textAppearance="@style/TextAppearance.Volume.Header" />
<com.android.keyguard.AlphaOptimizedImageButton
xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/packages/SystemUI/res/layout/volume_dialog_wrapped.xml b/packages/SystemUI/res/layout/volume_dialog_wrapped.xml
deleted file mode 100644
index 57489fd5f8d1..000000000000
--- a/packages/SystemUI/res/layout/volume_dialog_wrapped.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.systemui.HardwareUiLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="@dimen/top_padding"
- android:layout_marginBottom="@dimen/bottom_padding">
-
- <include layout="@layout/volume_dialog"/>
-
-</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 81ca23082367..74b0702ce5f6 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -398,4 +398,8 @@
it has been expanded to reveal its children. -->
<bool name="config_showGroupNotificationBgWhenExpanded">false</bool>
+ <!-- Whether to artificially interpret all signal strengths as
+ one bar higher than they actually are -->
+ <bool name="config_inflateSignalStrength">false</bool>
+
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1b2de8d8ea08..93d2072e955c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -216,6 +216,8 @@
<!-- The width of the panel that holds the quick settings. -->
<dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
+ <dimen name="volume_dialog_panel_width">@dimen/standard_notification_panel_width</dimen>
+
<!-- Gravity for the notification panel -->
<integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
@@ -800,7 +802,6 @@
<dimen name="hwui_edge_margin">16dp</dimen>
- <dimen name="volume_dialog_panel_width">315dp</dimen>
<dimen name="global_actions_panel_width">125dp</dimen>
<dimen name="global_actions_top_padding">100dp</dimen>
@@ -819,11 +820,14 @@
<dimen name="edge_margin">16dp</dimen>
<dimen name="rounded_corner_radius">0dp</dimen>
- <dimen name="rounded_corner_content_padding">0dp</dimen>
+ <dimen name="rounded_corner_content_padding">8dp</dimen>
<!-- Intended corner radius when drawing the mobile signal -->
<dimen name="stat_sys_mobile_signal_corner_radius">0.75dp</dimen>
<!-- How far to inset the rounded edges -->
<dimen name="stat_sys_mobile_signal_circle_inset">0.9dp</dimen>
+ <!-- Width of the hollow triangle for empty signal state -->
+ <dimen name="mobile_signal_empty_strokewidth">2dp</dimen>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
index 7af4a90e1a86..14e15ec5716d 100644
--- a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -55,11 +55,17 @@ public class RoundedCorners extends SystemUI implements Tunable {
public void start() {
mRoundedDefault = mContext.getResources().getDimensionPixelSize(
R.dimen.rounded_corner_radius);
- if (mRoundedDefault == 0) {
- // No rounded corners on this device.
- return;
+ if (mRoundedDefault != 0) {
+ setupRounding();
}
+ int padding = mContext.getResources().getDimensionPixelSize(
+ R.dimen.rounded_corner_content_padding);
+ if (padding != 0) {
+ setupPadding(padding);
+ }
+ }
+ private void setupRounding() {
mOverlay = LayoutInflater.from(mContext)
.inflate(R.layout.rounded_corners, null);
mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
@@ -82,10 +88,10 @@ public class RoundedCorners extends SystemUI implements Tunable {
mDensity = metrics.density;
Dependency.get(TunerService.class).addTunable(this, SIZE);
+ }
+ private void setupPadding(int padding) {
// Add some padding to all the content near the edge of the screen.
- int padding = mContext.getResources().getDimensionPixelSize(
- R.dimen.rounded_corner_content_padding);
StatusBar sb = getComponent(StatusBar.class);
View statusBar = sb.getStatusBarWindow();
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 699fdef3180a..6777ea2ef877 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.RectF;
import android.os.Handler;
+import android.util.ArrayMap;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -37,8 +38,6 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.FlingAnimationUtils;
-import java.util.HashMap;
-
public class SwipeHelper implements Gefingerpoken {
static final String TAG = "com.android.systemui.SwipeHelper";
private static final boolean DEBUG = false;
@@ -51,10 +50,10 @@ public class SwipeHelper implements Gefingerpoken {
public static final int X = 0;
public static final int Y = 1;
- private float SWIPE_ESCAPE_VELOCITY = 500f; // dp/sec
- private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
- private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
- private int MAX_DISMISS_VELOCITY = 4000; // dp/sec
+ private static final float SWIPE_ESCAPE_VELOCITY = 500f; // dp/sec
+ private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
+ private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
+ private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec
private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width
@@ -65,13 +64,13 @@ public class SwipeHelper implements Gefingerpoken {
private float mMinSwipeProgress = 0f;
private float mMaxSwipeProgress = 1f;
- private FlingAnimationUtils mFlingAnimationUtils;
+ private final FlingAnimationUtils mFlingAnimationUtils;
private float mPagingTouchSlop;
- private Callback mCallback;
- private Handler mHandler;
- private int mSwipeDirection;
- private VelocityTracker mVelocityTracker;
- private FalsingManager mFalsingManager;
+ private final Callback mCallback;
+ private final Handler mHandler;
+ private final int mSwipeDirection;
+ private final VelocityTracker mVelocityTracker;
+ private final FalsingManager mFalsingManager;
private float mInitialTouchPos;
private float mPerpendicularInitialTouchPos;
@@ -86,16 +85,16 @@ public class SwipeHelper implements Gefingerpoken {
private boolean mLongPressSent;
private LongPressListener mLongPressListener;
private Runnable mWatchLongPress;
- private long mLongPressTimeout;
+ private final long mLongPressTimeout;
final private int[] mTmpPos = new int[2];
- private int mFalsingThreshold;
+ private final int mFalsingThreshold;
private boolean mTouchAboveFalsingThreshold;
private boolean mDisableHwLayers;
- private boolean mFadeDependingOnAmountSwiped;
- private Context mContext;
+ private final boolean mFadeDependingOnAmountSwiped;
+ private final Context mContext;
- private HashMap<View, Animator> mDismissPendingMap = new HashMap<>();
+ private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>();
public SwipeHelper(int swipeDirection, Callback callback, Context context) {
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
index 880951036661..4ff10e975b1a 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/ExtensionFragmentListener.java
@@ -34,12 +34,14 @@ public class ExtensionFragmentListener<T extends FragmentBase> implements Consum
private final FragmentHostManager mFragmentHostManager;
private final String mTag;
private final Extension<T> mExtension;
+ private final int mId;
private String mOldClass;
private ExtensionFragmentListener(View view, String tag, int id, Extension<T> extension) {
mTag = tag;
mFragmentHostManager = FragmentHostManager.get(view);
mExtension = extension;
+ mId = id;
mFragmentHostManager.getFragmentManager().beginTransaction()
.replace(id, (Fragment) mExtension.get(), mTag)
.commit();
@@ -49,7 +51,7 @@ public class ExtensionFragmentListener<T extends FragmentBase> implements Consum
public void accept(T extension) {
try {
Fragment.class.cast(extension);
- mFragmentHostManager.getExtensionManager().setCurrentExtension(mTag,
+ mFragmentHostManager.getExtensionManager().setCurrentExtension(mId, mTag,
mOldClass, extension.getClass().getName(), mExtension.getContext());
mOldClass = extension.getClass().getName();
} catch (ClassCastException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index 871f113ac95e..f8f364da089b 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -266,16 +266,14 @@ public class FragmentHostManager {
class ExtensionFragmentManager {
private final ArrayMap<String, Context> mExtensionLookup = new ArrayMap<>();
- public void setCurrentExtension(@NonNull String tag, @Nullable String oldClass,
+ public void setCurrentExtension(int id, @NonNull String tag, @Nullable String oldClass,
@NonNull String currentClass, @Nullable Context context) {
- Fragment fragment = getFragmentManager().findFragmentByTag(tag);
if (oldClass != null) {
mExtensionLookup.remove(oldClass);
}
mExtensionLookup.put(currentClass, context);
getFragmentManager().beginTransaction()
- .replace(((View) fragment.getView().getParent()).getId(),
- instantiate(context, currentClass, null), tag)
+ .replace(id, instantiate(context, currentClass, null), tag)
.commit();
reloadFragments();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
index 32b5862e2b6b..af2b7677dcad 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
@@ -38,6 +38,7 @@ import android.util.Log;
import android.view.View;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
/**
* Bouncer between work activities and the activity used to confirm credentials before unlocking
@@ -83,6 +84,7 @@ public class WorkLockActivity extends Activity {
// Blank out the activity. When it is on-screen it will look like a Recents thumbnail with
// redaction switched on.
final View blankView = new View(this);
+ blankView.setContentDescription(getString(R.string.accessibility_desc_work_lock));
blankView.setBackgroundColor(getPrimaryColor());
setContentView(blankView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 0373d77940d7..ebf4b5d83029 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -93,6 +93,7 @@ public class PipManager implements BasePipManager {
ComponentName topPipActivity = PipUtils.getTopPinnedActivity(mContext,
mActivityManager);
mMenuController.hideMenu();
+ mTouchHandler.onActivityUnpinned(topPipActivity);
mNotificationController.onActivityUnpinned(topPipActivity);
SystemServicesProxy.getInstance(mContext).setPipVisibility(topPipActivity != null);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index ddaeb04f8443..3682ae655f7c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -25,6 +25,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.IActivityManager;
+import android.content.ComponentName;
import android.content.Context;
import android.graphics.Point;
import android.graphics.PointF;
@@ -116,7 +117,7 @@ public class PipTouchHandler {
};
// Behaviour states
- private int mMenuState;
+ private int mMenuState = MENU_STATE_NONE;
private boolean mIsMinimized;
private boolean mIsImeShowing;
private int mImeHeight;
@@ -212,14 +213,15 @@ public class PipTouchHandler {
}
public void onActivityPinned() {
- // Reset some states once we are pinned
- mMenuState = MENU_STATE_NONE;
+ cleanUp();
+ mShowPipMenuOnAnimationEnd = true;
+ }
- if (mIsMinimized) {
- setMinimizedStateInternal(false);
+ public void onActivityUnpinned(ComponentName topPipActivity) {
+ if (topPipActivity == null) {
+ // Clean up state after the last PiP activity is removed
+ cleanUp();
}
- cleanUpDismissTarget();
- mShowPipMenuOnAnimationEnd = true;
}
public void onPinnedStackAnimationEnded() {
@@ -729,6 +731,16 @@ public class PipTouchHandler {
mDismissViewController.destroyDismissTarget();
}
+ /**
+ * Resets some states related to the touch handling.
+ */
+ private void cleanUp() {
+ if (mIsMinimized) {
+ setMinimizedStateInternal(false);
+ }
+ cleanUpDismissTarget();
+ }
+
public void dump(PrintWriter pw, String prefix) {
final String innerPrefix = prefix + " ";
pw.println(prefix + TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
index f0745a0791ef..ac41b752020b 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipNotification.java
@@ -174,7 +174,7 @@ public class PipNotification {
void onConfigurationChanged(Context context) {
Resources res = context.getResources();
mDefaultTitle = res.getString(R.string.pip_notification_unknown_title);
- mDefaultIconResId = R.drawable.pip_expand;
+ mDefaultIconResId = R.drawable.pip_icon;
if (mNotified) {
// update notification
notifyPipNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index e6c3520c4d62..81ec6a7c72a9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -141,7 +141,11 @@ public class CellularTile extends QSTileImpl<SignalState> {
&& mDataController.isMobileDataEnabled();
state.icon = new SignalIcon(cb.mobileSignalIconId);
- state.state = Tile.STATE_ACTIVE;
+ if (cb.airplaneModeEnabled) {
+ state.state = Tile.STATE_INACTIVE;
+ } else {
+ state.state = Tile.STATE_ACTIVE;
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index dca4a8d3308a..9ca756c5431f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -878,7 +878,8 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC
// Recents doesn't care about the wallpaper being visible or not, it always
// wants to scrim with wallpaper colors
mBackgroundScrim.setColors(
- mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM, true));
+ mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
+ ColorExtractor.TYPE_DARK, true));
}
}
@@ -886,7 +887,7 @@ public class RecentsView extends FrameLayout implements ColorExtractor.OnColorsC
mColorExtractor.addOnColorsChangedListener(this);
// Getting system scrim colors ignoring wallpaper visibility since it should never be grey.
ColorExtractor.GradientColors systemColors = mColorExtractor.getColors(
- WallpaperManager.FLAG_SYSTEM, true);
+ ColorExtractor.TYPE_DARK, WallpaperManager.FLAG_SYSTEM, true);
// We don't want to interpolate colors because we're defining the initial state.
// Gradient should be set/ready when you open "Recents".
mBackgroundScrim.setColors(systemColors, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 67ea25870a45..97e2f6d3e6f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -465,7 +465,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
|| row.getTranslationZ() > mAmbientState.getBaseZHeight()))) {
iconState.hidden = true;
}
- int shelfColor = icon.getStaticDrawableColor();
+ int backgroundColor = getBackgroundColorWithoutTint();
+ int shelfColor = icon.getContrastedStaticDrawableColor(backgroundColor);
if (!noIcon && shelfColor != StatusBarIconView.NO_COLOR) {
int iconColor = row.getVisibleNotificationHeader().getOriginalIconColor();
shelfColor = NotificationUtils.interpolateColors(iconColor, shelfColor,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 3c7ddb502145..1a47e4428e49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -35,6 +35,7 @@ import android.graphics.drawable.Icon;
import android.os.Parcelable;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
+import android.support.v4.graphics.ColorUtils;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.FloatProperty;
@@ -46,6 +47,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Interpolator;
import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.NotificationColorUtil;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.NotificationIconDozeHelper;
@@ -127,6 +129,8 @@ public class StatusBarIconView extends AnimatedImageView {
setColorInternal(newColor);
};
private final NotificationIconDozeHelper mDozer;
+ private int mContrastedDrawableColor;
+ private int mCachedContrastBackgroundColor = NO_COLOR;
public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
this(context, slot, sbn, false);
@@ -528,6 +532,7 @@ public class StatusBarIconView extends AnimatedImageView {
public void setStaticDrawableColor(int color) {
mDrawableColor = color;
setColorInternal(color);
+ updateContrastedStaticColor();
mIconColor = color;
mDozer.setColor(color);
}
@@ -580,6 +585,42 @@ public class StatusBarIconView extends AnimatedImageView {
return mDrawableColor;
}
+ /**
+ * A drawable color that passes GAR on a specific background.
+ * This value is cached.
+ *
+ * @param backgroundColor Background to test against.
+ * @return GAR safe version of {@link StatusBarIconView#getStaticDrawableColor()}.
+ */
+ int getContrastedStaticDrawableColor(int backgroundColor) {
+ if (mCachedContrastBackgroundColor != backgroundColor) {
+ mCachedContrastBackgroundColor = backgroundColor;
+ updateContrastedStaticColor();
+ }
+ return mContrastedDrawableColor;
+ }
+
+ private void updateContrastedStaticColor() {
+ if (mCachedContrastBackgroundColor == NO_COLOR) {
+ return;
+ }
+ // We'll modify the color if it doesn't pass GAR
+ int contrastedColor = mDrawableColor;
+ if (!NotificationColorUtil.satisfiesTextContrast(mCachedContrastBackgroundColor,
+ contrastedColor)) {
+ float[] hsl = new float[3];
+ ColorUtils.colorToHSL(mDrawableColor, hsl);
+ // This is basically a light grey, pushing the color will only distort it.
+ // Best thing to do in here is to fallback to the default color.
+ if (hsl[1] < 0.2f) {
+ contrastedColor = Notification.COLOR_DEFAULT;
+ }
+ contrastedColor = NotificationColorUtil.resolveContrastColor(mContext,
+ contrastedColor, mCachedContrastBackgroundColor);
+ }
+ mContrastedDrawableColor = contrastedColor;
+ }
+
public void setVisibleState(int state) {
setVisibleState(state, true /* animate */, null /* endRunnable */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 9275358e78bd..419aefe3e9e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -81,9 +81,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
private final SysuiColorExtractor mColorExtractor;
private ColorExtractor.GradientColors mLockColors;
- private ColorExtractor.GradientColors mLockColorsDark;
private ColorExtractor.GradientColors mSystemColors;
- private ColorExtractor.GradientColors mSystemColorsDark;
private boolean mNeedsDrawableColorUpdate;
protected float mScrimBehindAlpha;
@@ -135,13 +133,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mColorExtractor.addOnColorsChangedListener(this);
mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
- ColorExtractor.TYPE_NORMAL, true /* ignoreVisibility */);
- mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
- ColorExtractor.TYPE_NORMAL, true /* ignoreVisibility */);
- // Darker gradient for the top scrim (mScrimInFront)
- mLockColorsDark = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
- mSystemColorsDark = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
+ mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
mNeedsDrawableColorUpdate = true;
@@ -311,13 +304,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
mNeedsDrawableColorUpdate = false;
if (mKeyguardShowing) {
// Always animate color changes if we're seeing the keyguard
- mScrimInFront.setColors(mLockColorsDark);
+ mScrimInFront.setColors(mLockColors);
mScrimBehind.setColors(mLockColors);
} else {
// Only animate scrim color if the scrim view is actually visible
boolean animateScrimInFront = mScrimInFront.getViewAlpha() != 0;
boolean animateScrimBehind = mScrimBehind.getViewAlpha() != 0;
- mScrimInFront.setColors(mSystemColorsDark, animateScrimInFront);
+ mScrimInFront.setColors(mSystemColors, animateScrimInFront);
mScrimBehind.setColors(mSystemColors, animateScrimBehind);
}
}
@@ -663,16 +656,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
public void onColorsChanged(ColorExtractor colorExtractor, int which) {
if ((which & WallpaperManager.FLAG_LOCK) != 0) {
mLockColors = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
- ColorExtractor.TYPE_NORMAL, true /* ignoreVisibility */);
- mLockColorsDark = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK,
ColorExtractor.TYPE_DARK, true /* ignoreVisibility */);
mNeedsDrawableColorUpdate = true;
scheduleUpdate();
}
if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
mSystemColors = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
- ColorExtractor.TYPE_NORMAL, mKeyguardShowing);
- mSystemColorsDark = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM,
ColorExtractor.TYPE_DARK, mKeyguardShowing);
mNeedsDrawableColorUpdate = true;
scheduleUpdate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
index 083da518eba4..deea521b7c2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -21,13 +21,15 @@ import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.Matrix;
import android.graphics.Paint;
-import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.Path.FillType;
import android.graphics.Path.Op;
+import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.LayoutDirection;
@@ -63,6 +65,7 @@ public class SignalDrawable extends Drawable {
private static final int STATE_EMPTY = 1;
private static final int STATE_CUT = 2;
private static final int STATE_CARRIER_CHANGE = 3;
+ private static final int STATE_AIRPLANE = 4;
private static final long DOT_DELAY = 1000;
@@ -97,6 +100,17 @@ public class SignalDrawable extends Drawable {
// How far the circle defining the corners is inset from the edges
private final float mAppliedCornerInset;
+ // The easiest way to understand this is as if we set Style.STROKE and draw the triangle,
+ // but that is only theoretically right. Instead, draw the triangle and clip out a smaller
+ // one inset by this amount.
+ private final float mEmptyStrokeWidth;
+ private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f);
+ private final float mEmptyDiagInset; // == mEmptyStrokeWidth * INV_TAN
+
+ // Where the top and left points of the triangle would be if not for rounding
+ private final PointF mVirtualTop = new PointF();
+ private final PointF mVirtualLeft = new PointF();
+
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final int mDarkModeBackgroundColor;
@@ -106,6 +120,10 @@ public class SignalDrawable extends Drawable {
private final Path mFullPath = new Path();
private final Path mForegroundPath = new Path();
private final Path mXPath = new Path();
+ // Cut out when STATE_EMPTY
+ private final Path mCutPath = new Path();
+ // Draws the slash when in airplane mode
+ private final SlashArtist mSlash = new SlashArtist();
private final Handler mHandler;
private float mOldDarkIntensity = -1;
private float mNumLevels = 1;
@@ -126,6 +144,12 @@ public class SignalDrawable extends Drawable {
mLightModeFillColor =
Utils.getDefaultColor(context, R.color.light_mode_icon_color_dual_tone_fill);
mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
+
+ // mCutPath parameters
+ mEmptyStrokeWidth = context.getResources()
+ .getDimensionPixelSize(R.dimen.mobile_signal_empty_strokewidth);
+ mEmptyDiagInset = mEmptyStrokeWidth * INV_TAN;
+
mHandler = new Handler();
setDarkIntensity(0);
@@ -224,9 +248,10 @@ public class SignalDrawable extends Drawable {
}
mFullPath.reset();
mFullPath.setFillType(FillType.WINDING);
+
final float width = getBounds().width();
final float height = getBounds().height();
- final float padding = (int) (PAD * width); // Stay on pixel boundary
+ final float padding = Math.round(PAD * width);
final float cornerRadius = RADIUS_RATIO * height;
// Offset from circle where the hypotenuse meets the circle
final float diagOffset = DIAG_OFFSET_MULTIPLIER * cornerRadius;
@@ -292,10 +317,37 @@ public class SignalDrawable extends Drawable {
mFullPath.rLineTo(0, cut);
}
- mPaint.setStyle(mState == STATE_EMPTY ? Style.STROKE : Style.FILL);
- mForegroundPaint.setStyle(mState == STATE_EMPTY ? Style.STROKE : Style.FILL);
-
- if (mState != STATE_CARRIER_CHANGE) {
+ if (mState == STATE_EMPTY) {
+ // Where the corners would be if this were a real triangle
+ mVirtualTop.set(
+ width - padding,
+ (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius));
+ mVirtualLeft.set(
+ (padding + cornerRadius + mAppliedCornerInset) - (INV_TAN * cornerRadius),
+ height - padding);
+
+ // Cut out a smaller triangle from the center of mFullPath
+ mCutPath.reset();
+ mCutPath.setFillType(FillType.WINDING);
+ mCutPath.moveTo(width - padding - mEmptyStrokeWidth,
+ height - padding - mEmptyStrokeWidth);
+ mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
+ mVirtualTop.y + mEmptyDiagInset);
+ mCutPath.lineTo(mVirtualLeft.x + mEmptyDiagInset,
+ height - padding - mEmptyStrokeWidth);
+ mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
+ height - padding - mEmptyStrokeWidth);
+
+ // In empty state, draw the full path as the foreground paint
+ mForegroundPath.set(mFullPath);
+ mFullPath.reset();
+ mForegroundPath.op(mCutPath, Path.Op.DIFFERENCE);
+ } else if (mState == STATE_AIRPLANE) {
+ // Airplane mode is slashed, full-signal
+ mForegroundPath.set(mFullPath);
+ mFullPath.reset();
+ mSlash.draw((int) height, (int) width, canvas, mForegroundPaint);
+ } else if (mState != STATE_CARRIER_CHANGE) {
mForegroundPath.reset();
int sigWidth = Math.round(calcFit(mLevel / (mNumLevels - 1)) * (width - 2 * padding));
mForegroundPath.addRect(padding, padding, padding + sigWidth, height - padding,
@@ -405,4 +457,65 @@ public class SignalDrawable extends Drawable {
public static int getEmptyState(int numLevels) {
return (STATE_EMPTY << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT);
}
+
+ public static int getAirplaneModeState(int numLevels) {
+ return (STATE_AIRPLANE << STATE_SHIFT) | (numLevels << NUM_LEVEL_SHIFT);
+ }
+
+ private final class SlashArtist {
+ // These values are derived in un-rotated (vertical) orientation
+ private static final float SLASH_WIDTH = 1.8384776f;
+ private static final float SLASH_HEIGHT = 22f;
+ private static final float CENTER_X = 10.65f;
+ private static final float CENTER_Y = 15.869239f;
+ private static final float SCALE = 24f;
+
+ // Bottom is derived during animation
+ private static final float LEFT = (CENTER_X - (SLASH_WIDTH / 2)) / SCALE;
+ private static final float TOP = (CENTER_Y - (SLASH_HEIGHT / 2)) / SCALE;
+ private static final float RIGHT = (CENTER_X + (SLASH_WIDTH / 2)) / SCALE;
+ private static final float BOTTOM = (CENTER_Y + (SLASH_HEIGHT / 2)) / SCALE;
+ // Draw the slash washington-monument style; rotate to no-u-turn style
+ private static final float ROTATION = -45f;
+
+ private final Path mPath = new Path();
+ private final RectF mSlashRect = new RectF();
+
+ void draw(int height, int width, @NonNull Canvas canvas, Paint paint) {
+ Matrix m = new Matrix();
+ updateRect(
+ scale(LEFT, width),
+ scale(TOP, height),
+ scale(RIGHT, width),
+ scale(BOTTOM, height));
+
+ mPath.reset();
+ // Draw the slash vertically
+ mPath.addRect(mSlashRect, Direction.CW);
+ m.setRotate(ROTATION, width / 2, height / 2);
+ mPath.transform(m);
+ canvas.drawPath(mPath, paint);
+
+ // Rotate back to vertical, and draw the cut-out rect next to this one
+ m.setRotate(-ROTATION, width / 2, height / 2);
+ mPath.transform(m);
+ m.setTranslate(mSlashRect.width(), 0);
+ mPath.transform(m);
+ mPath.addRect(mSlashRect, Direction.CW);
+ m.setRotate(ROTATION, width / 2, height / 2);
+ mPath.transform(m);
+ canvas.clipOutPath(mPath);
+ }
+
+ void updateRect(float left, float top, float right, float bottom) {
+ mSlashRect.left = left;
+ mSlashRect.top = top;
+ mSlashRect.right = right;
+ mSlashRect.bottom = bottom;
+ }
+
+ private float scale(float frac, int width) {
+ return frac * width;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index d8db3222734d..4d6fd9c136b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3465,7 +3465,9 @@ public class StatusBar extends SystemUI implements DemoMode,
pw.println(Settings.Global.zenModeToString(mZenMode));
pw.print(" mUseHeadsUp=");
pw.println(mUseHeadsUp);
- dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+ if (mStatusBarView != null) {
+ dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
+ }
pw.print(" mMediaSessionManager=");
pw.println(mMediaSessionManager);
@@ -3531,7 +3533,9 @@ public class StatusBar extends SystemUI implements DemoMode,
pw.println(" mGroupManager: null");
}
- mLightBarController.dump(fd, pw, args);
+ if (mLightBarController != null) {
+ mLightBarController.dump(fd, pw, args);
+ }
if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 3f5f5a0ed5ae..874f0d9d5b5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -31,8 +31,10 @@ import android.os.Message;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.support.annotation.VisibleForTesting;
import com.android.systemui.R;
+import com.android.systemui.util.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -141,7 +143,8 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio
/**
* Returns true if there currently exist active high power location requests.
*/
- private boolean areActiveHighPowerLocationRequests() {
+ @VisibleForTesting
+ protected boolean areActiveHighPowerLocationRequests() {
List<AppOpsManager.PackageOps> packages
= mAppOpsManager.getPackagesForOps(mHighPowerRequestAppOpArray);
// AppOpsManager can return null when there is no requested data.
@@ -205,16 +208,14 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio
}
private void locationActiveChanged() {
- for (LocationChangeCallback cb : mSettingsChangeCallbacks) {
- cb.onLocationActiveChanged(mAreActiveLocationRequests);
- }
+ Utils.safeForeach(mSettingsChangeCallbacks,
+ cb -> cb.onLocationActiveChanged(mAreActiveLocationRequests));
}
private void locationSettingsChanged() {
boolean isEnabled = isLocationEnabled();
- for (LocationChangeCallback cb : mSettingsChangeCallbacks) {
- cb.onLocationSettingsChanged(isEnabled);
- }
+ Utils.safeForeach(mSettingsChangeCallbacks,
+ cb -> cb.onLocationSettingsChanged(isEnabled));
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 67b5596e34c9..bd7fee0f7f52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -235,6 +235,9 @@ public class MobileSignalController extends SignalController<
}
private int getNumLevels() {
+ if (mConfig.inflateSignalStrengths) {
+ return SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1;
+ }
return SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
}
@@ -243,7 +246,11 @@ public class MobileSignalController extends SignalController<
if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) {
return SignalDrawable.getCarrierChangeState(getNumLevels());
} else if (mCurrentState.connected) {
- return SignalDrawable.getState(mCurrentState.level, getNumLevels(),
+ int level = mCurrentState.level;
+ if (mConfig.inflateSignalStrengths) {
+ level++;
+ }
+ return SignalDrawable.getState(level, getNumLevels(),
mCurrentState.inetCondition == 0);
} else if (mCurrentState.enabled) {
return SignalDrawable.getEmptyState(getNumLevels());
@@ -254,6 +261,10 @@ public class MobileSignalController extends SignalController<
@Override
public int getQsCurrentIconId() {
+ if (mCurrentState.airplaneMode) {
+ return SignalDrawable.getAirplaneModeState(getNumLevels());
+ }
+
return getCurrentIconId();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 39f7d1295d1b..c217bda935c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -958,6 +958,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
boolean show4gForLte = false;
boolean hideLtePlus = false;
boolean hspaDataDistinguishable;
+ boolean inflateSignalStrengths = false;
static Config readConfig(Context context) {
Config config = new Config();
@@ -970,6 +971,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
config.hspaDataDistinguishable =
res.getBoolean(R.bool.config_hspa_data_distinguishable);
config.hideLtePlus = res.getBoolean(R.bool.config_hideLtePlus);
+ config.inflateSignalStrengths = res.getBoolean(R.bool.config_inflateSignalStrength);
return config;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 2742fdd0dd84..2b2ad693608e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -18,7 +18,6 @@ package com.android.systemui.volume;
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.animation.ObjectAnimator;
@@ -32,10 +31,12 @@ import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.AudioSystem;
@@ -48,9 +49,11 @@ import android.provider.Settings.Global;
import android.transition.AutoTransition;
import android.transition.Transition;
import android.transition.TransitionManager;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.AccessibilityDelegate;
@@ -71,7 +74,6 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
-import com.android.systemui.HardwareUiLayout;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.colorextraction.SysuiColorExtractor;
@@ -96,8 +98,7 @@ import java.util.List;
*
* Methods ending in "H" must be called on the (ui) handler.
*/
-public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
- ColorExtractor.OnColorsChangedListener {
+public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable {
private static final String TAG = Util.logTag(VolumeDialogImpl.class);
public static final String SHOW_FULL_ZEN = "sysui_show_full_zen";
@@ -107,8 +108,6 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
private final Context mContext;
private final H mHandler = new H();
- private final GradientDrawable mGradientDrawable;
- private final ColorExtractor mColorExtractor;
private final VolumeDialogController mController;
private Window mWindow;
@@ -163,9 +162,6 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
(AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
mActiveSliderTint = ColorStateList.valueOf(Utils.getColorAccent(mContext));
mInactiveSliderTint = loadColorStateList(R.color.volume_slider_inactive);
- mGradientDrawable = new GradientDrawable(mContext);
- mGradientDrawable.setAlpha((int) (ScrimController.GRADIENT_SCRIM_ALPHA * 255));
- mColorExtractor = Dependency.get(SysuiColorExtractor.class);
}
public void init(int windowType, Callback callback) {
@@ -187,7 +183,6 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
@Override
public void destroy() {
mController.removeCallback(mControllerCallbackH);
- mColorExtractor.removeOnColorsChangedListener(this);
}
private void initDialog() {
@@ -198,52 +193,64 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
mShowing = false;
mWindow = mDialog.getWindow();
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
- mWindow.setBackgroundDrawable(mGradientDrawable);
+ mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
- | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
- Point displaySize = new Point();
- mContext.getDisplay().getRealSize(displaySize);
+ | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+ | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
mDialog.setCanceledOnTouchOutside(true);
final Resources res = mContext.getResources();
+ final WindowManager.LayoutParams lp = mWindow.getAttributes();
+ lp.type = mWindowType;
+ lp.format = PixelFormat.TRANSLUCENT;
+ lp.setTitle(VolumeDialogImpl.class.getSimpleName());
+ lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
+ lp.y = res.getDimensionPixelSize(R.dimen.volume_offset_top);
+ lp.gravity = Gravity.TOP;
+ lp.windowAnimations = -1;
+ mWindow.setAttributes(lp);
mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
- mDialog.setContentView(R.layout.volume_dialog_wrapped);
- mDialogView = mDialog.findViewById(R.id.volume_dialog);
- mDialogView.setOnHoverListener((v, event) -> {
- int action = event.getActionMasked();
- mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
- || (action == MotionEvent.ACTION_HOVER_MOVE);
- rescheduleTimeoutH();
- return true;
+ mDialog.setContentView(R.layout.volume_dialog);
+ mDialogView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog);
+ mDialogView.setOnHoverListener(new View.OnHoverListener() {
+ @Override
+ public boolean onHover(View v, MotionEvent event) {
+ int action = event.getActionMasked();
+ mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
+ || (action == MotionEvent.ACTION_HOVER_MOVE);
+ rescheduleTimeoutH();
+ return true;
+ }
});
- mColorExtractor.addOnColorsChangedListener(this);
- mGradientDrawable.setScreenSize(displaySize.x, displaySize.y);
-
mDialogContentView = mDialog.findViewById(R.id.volume_dialog_content);
mDialogRowsView = mDialogContentView.findViewById(R.id.volume_dialog_rows);
mExpanded = false;
- mExpandButton = mDialogView.findViewById(R.id.volume_expand_button);
+ mExpandButton = (ImageButton) mDialogView.findViewById(R.id.volume_expand_button);
mExpandButton.setOnClickListener(mClickExpand);
mExpandButton.setVisibility(
AudioSystem.isSingleVolume(mContext) ? View.GONE : View.VISIBLE);
+ updateWindowWidthH();
updateExpandButtonH();
- mMotion = new VolumeDialogMotion(mDialog, (View) mDialogView.getParent(),
- mDialogContentView, mExpandButton, mGradientDrawable, animating -> {
- if (animating) return;
- if (mPendingStateChanged) {
- mHandler.sendEmptyMessage(H.STATE_CHANGED);
- mPendingStateChanged = false;
- }
- if (mPendingRecheckAll) {
- mHandler.sendEmptyMessage(H.RECHECK_ALL);
- mPendingRecheckAll = false;
+ mMotion = new VolumeDialogMotion(mDialog, mDialogView, mDialogContentView, mExpandButton,
+ new VolumeDialogMotion.Callback() {
+ @Override
+ public void onAnimatingChanged(boolean animating) {
+ if (animating) return;
+ if (mPendingStateChanged) {
+ mHandler.sendEmptyMessage(H.STATE_CHANGED);
+ mPendingStateChanged = false;
+ }
+ if (mPendingRecheckAll) {
+ mHandler.sendEmptyMessage(H.RECHECK_ALL);
+ mPendingRecheckAll = false;
+ }
}
});
@@ -268,20 +275,11 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
addExistingRows();
}
mExpandButtonAnimationDuration = res.getInteger(R.integer.volume_expand_animation_duration);
- mZenFooter = mDialog.findViewById(R.id.volume_zen_footer);
+ mZenFooter = (ZenFooter) mDialog.findViewById(R.id.volume_zen_footer);
mZenFooter.init(mZenModeController);
- mZenPanel = mDialog.findViewById(R.id.tuner_zen_mode_panel);
+ mZenPanel = (TunerZenModePanel) mDialog.findViewById(R.id.tuner_zen_mode_panel);
mZenPanel.init(mZenModeController);
mZenPanel.setCallback(mZenPanelCallback);
-
- final WindowManager.LayoutParams lp = mWindow.getAttributes();
- lp.width = MATCH_PARENT;
- lp.height = MATCH_PARENT;
- lp.type = mWindowType;
- lp.format = PixelFormat.TRANSLUCENT;
- lp.setTitle(VolumeDialogImpl.class.getSimpleName());
- lp.windowAnimations = -1;
- mWindow.setAttributes(lp);
}
@Override
@@ -295,6 +293,20 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
return ColorStateList.valueOf(mContext.getColor(colorResId));
}
+ private void updateWindowWidthH() {
+ final ViewGroup.LayoutParams lp = mDialogView.getLayoutParams();
+ final DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
+ if (D.BUG) Log.d(TAG, "updateWindowWidth dm.w=" + dm.widthPixels);
+ int w = dm.widthPixels;
+ final int max = mContext.getResources()
+ .getDimensionPixelSize(R.dimen.volume_dialog_panel_width);
+ if (w > max) {
+ w = max;
+ }
+ lp.width = w;
+ mDialogView.setLayoutParams(lp);
+ }
+
public void setStreamImportant(int stream, boolean important) {
mHandler.obtainMessage(H.SET_STREAM_IMPORTANT, stream, important ? 1 : 0).sendToTarget();
}
@@ -478,10 +490,6 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
rescheduleTimeoutH();
if (mShowing) return;
mShowing = true;
- ColorExtractor.GradientColors colors = mColorExtractor.getColors(
- mKeyguard.isKeyguardLocked() ? WallpaperManager.FLAG_LOCK
- : WallpaperManager.FLAG_SYSTEM);
- mGradientDrawable.setColors(colors, false);
mMotion.startShow();
Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
mController.notifyVisible(true);
@@ -539,8 +547,10 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
}
private void updateDialogBottomMarginH() {
+ final long diff = System.currentTimeMillis() - mCollapseTime;
+ final boolean collapsing = mCollapseTime != 0 && diff < getConservativeCollapseDuration();
final ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) mDialogView.getLayoutParams();
- final int bottomMargin =
+ final int bottomMargin = collapsing ? mDialogContentView.getHeight() :
mContext.getResources().getDimensionPixelSize(R.dimen.volume_dialog_margin_bottom);
if (bottomMargin != mlp.bottomMargin) {
if (D.BUG) Log.d(TAG, "bottomMargin " + mlp.bottomMargin + " -> " + bottomMargin);
@@ -570,7 +580,7 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
TransitionManager.endTransitions(mDialogView);
final VolumeRow activeRow = getActiveRow();
if (!dismissing) {
- mWindow.setLayout(mWindow.getAttributes().width, MATCH_PARENT);
+ mWindow.setLayout(mWindow.getAttributes().width, ViewGroup.LayoutParams.MATCH_PARENT);
TransitionManager.beginDelayedTransition(mDialogView, getTransition());
}
updateRowsH(activeRow);
@@ -632,7 +642,7 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
final boolean isActive = row == activeRow;
final boolean shouldBeVisible = shouldBeVisibleH(row, isActive);
Util.setVisOrGone(row.view, shouldBeVisible);
- Util.setVisOrGone(row.header, shouldBeVisible && mExpanded);
+ Util.setVisOrGone(row.header, shouldBeVisible);
if (row.view.isShown()) {
updateVolumeRowSliderTintH(row, isActive);
}
@@ -689,18 +699,12 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
final boolean visible = mState.zenMode != Global.ZEN_MODE_OFF
&& (mAudioManager.isStreamAffectedByRingerMode(mActiveStream) || mExpanded)
&& !mZenPanel.isEditing();
-
- if (wasVisible != visible) {
- mZenFooter.update();
- if (visible) {
- HardwareUiLayout.get(mZenFooter).setDivisionView(mZenFooter);
- } else {
- mHandler.postDelayed(() ->
- HardwareUiLayout.get(mZenFooter).setDivisionView(mZenFooter),
- mExpandButtonAnimationDuration);
- }
- Util.setVisOrGone(mZenFooter, visible);
+ TransitionManager.beginDelayedTransition(mDialogView, getTransition());
+ if (wasVisible != visible && !visible) {
+ prepareForCollapse();
}
+ Util.setVisOrGone(mZenFooter, visible);
+ mZenFooter.update();
final boolean fullWasVisible = mZenPanel.getVisibility() == View.VISIBLE;
final boolean fullVisible = mShowFullZen && !visible;
@@ -960,7 +964,8 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
@Override
public void onTransitionEnd(Transition transition) {
- mWindow.setLayout(MATCH_PARENT, MATCH_PARENT);
+ mWindow.setLayout(
+ mWindow.getAttributes().width, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
@@ -969,7 +974,8 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
@Override
public void onTransitionPause(Transition transition) {
- mWindow.setLayout(MATCH_PARENT, MATCH_PARENT);
+ mWindow.setLayout(
+ mWindow.getAttributes().width, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override
@@ -1021,6 +1027,7 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
initDialog();
mDensity = density;
}
+ updateWindowWidthH();
mConfigurableTexts.update();
mZenFooter.onConfigurationChanged();
}
@@ -1076,26 +1083,10 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
if (mExpandButtonAnimationRunning) return;
final boolean newExpand = !mExpanded;
Events.writeEvent(mContext, Events.EVENT_EXPAND, newExpand);
- if (!newExpand) {
- HardwareUiLayout.get(mDialogContentView).setCollapse();
- }
updateExpandedH(newExpand, false /* dismissing */);
}
};
- @Override
- public void onColorsChanged(ColorExtractor extractor, int which) {
- if (mKeyguard.isKeyguardLocked()) {
- if ((WallpaperManager.FLAG_LOCK & which) != 0) {
- mGradientDrawable.setColors(extractor.getColors(WallpaperManager.FLAG_LOCK));
- }
- } else {
- if ((WallpaperManager.FLAG_SYSTEM & which) != 0) {
- mGradientDrawable.setColors(extractor.getColors(WallpaperManager.FLAG_SYSTEM));
- }
- }
- }
-
private final class H extends Handler {
private static final int SHOW = 1;
private static final int DISMISS = 2;
@@ -1167,8 +1158,8 @@ public class VolumeDialogImpl implements VolumeDialog, TunerService.Tunable,
event.setPackageName(mContext.getPackageName());
ViewGroup.LayoutParams params = getWindow().getAttributes();
- boolean isFullScreen = (params.width == MATCH_PARENT) &&
- (params.height == MATCH_PARENT);
+ boolean isFullScreen = (params.width == ViewGroup.LayoutParams.MATCH_PARENT) &&
+ (params.height == ViewGroup.LayoutParams.MATCH_PARENT);
event.setFullScreen(isFullScreen);
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
index 2df222764dcc..01d31e2a9852 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.systemui.volume;
import android.animation.Animator;
@@ -41,10 +42,8 @@ public class VolumeDialogMotion {
private final View mDialogView;
private final ViewGroup mContents; // volume rows + zen footer
private final View mChevron;
- private final Drawable mBackground;
private final Handler mHandler = new Handler();
private final Callback mCallback;
- private final int mBackgroundTargetAlpha;
private boolean mAnimating; // show or dismiss animation is running
private boolean mShowing; // show animation is running
@@ -53,14 +52,12 @@ public class VolumeDialogMotion {
private ValueAnimator mContentsPositionAnimator;
public VolumeDialogMotion(Dialog dialog, View dialogView, ViewGroup contents, View chevron,
- Drawable background, Callback callback) {
+ Callback callback) {
mDialog = dialog;
mDialogView = dialogView;
mContents = contents;
mChevron = chevron;
mCallback = callback;
- mBackground = background;
- mBackgroundTargetAlpha = mBackground.getAlpha();
mDialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
@@ -71,9 +68,8 @@ public class VolumeDialogMotion {
@Override
public void onShow(DialogInterface dialog) {
if (D.BUG) Log.d(TAG, "mDialog.onShow");
- final int w = mDialogView.getWidth() / 4;
- mDialogView.setTranslationX(w);
- mBackground.setAlpha(0);
+ final int h = mDialogView.getHeight();
+ mDialogView.setTranslationY(-h);
startShowAnimation();
}
});
@@ -122,7 +118,7 @@ public class VolumeDialogMotion {
}
private int chevronDistance() {
- return 0;
+ return mChevron.getHeight() / 6;
}
private int chevronPosY() {
@@ -133,29 +129,26 @@ public class VolumeDialogMotion {
private void startShowAnimation() {
if (D.BUG) Log.d(TAG, "startShowAnimation");
mDialogView.animate()
- .translationX(0)
.translationY(0)
- .alpha(1)
.setDuration(scaledDuration(300))
.setInterpolator(new LogDecelerateInterpolator())
.setListener(null)
.setUpdateListener(animation -> {
- mBackground.setAlpha(
- (int) (animation.getAnimatedFraction() * mBackgroundTargetAlpha));
if (mChevronPositionAnimator != null) {
final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
if (mChevronPositionAnimator == null) return;
// reposition chevron
final int posY = chevronPosY();
+ mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
}
})
.withEndAction(new Runnable() {
@Override
public void run() {
- mBackground.setAlpha(mBackgroundTargetAlpha);
if (mChevronPositionAnimator == null) return;
// reposition chevron
final int posY = chevronPosY();
+ mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
}
})
.start();
@@ -171,13 +164,19 @@ public class VolumeDialogMotion {
if (D.BUG) Log.d(TAG, "show.onAnimationEnd");
setShowing(false);
}
-
@Override
public void onAnimationCancel(Animator animation) {
if (D.BUG) Log.d(TAG, "show.onAnimationCancel");
mCancelled = true;
}
});
+ mContentsPositionAnimator.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float v = (Float) animation.getAnimatedValue();
+ mContents.setTranslationY(v + -mDialogView.getTranslationY());
+ }
+ });
mContentsPositionAnimator.setInterpolator(new LogDecelerateInterpolator());
mContentsPositionAnimator.start();
@@ -219,30 +218,34 @@ public class VolumeDialogMotion {
setShowing(false);
}
mDialogView.animate()
- .translationX(mDialogView.getWidth() / 4)
- .alpha(0)
+ .translationY(-mDialogView.getHeight())
.setDuration(scaledDuration(250))
.setInterpolator(new LogAccelerateInterpolator())
- .setUpdateListener(animation -> {
- final float v = 1 - mChevronPositionAnimator.getAnimatedFraction();
- mBackground.setAlpha((int) (v * mBackgroundTargetAlpha));
+ .setUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mContents.setTranslationY(-mDialogView.getTranslationY());
+ final int posY = chevronPosY();
+ mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
+ }
})
.setListener(new AnimatorListenerAdapter() {
private boolean mCancelled;
-
@Override
public void onAnimationEnd(Animator animation) {
if (mCancelled) return;
if (D.BUG) Log.d(TAG, "dismiss.onAnimationEnd");
- mHandler.postDelayed(() -> {
- if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
- mDialog.dismiss();
- onComplete.run();
- setDismissing(false);
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
+ mDialog.dismiss();
+ onComplete.run();
+ setDismissing(false);
+ }
}, PRE_DISMISS_DELAY);
}
-
@Override
public void onAnimationCancel(Animator animation) {
if (D.BUG) Log.d(TAG, "dismiss.onAnimationCancel");
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 612a54a8d70d..b12fd1c9ba89 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -37,6 +37,7 @@
<uses-permission android:name="android.permission.REQUEST_NETWORK_SCORES" />
<uses-permission android:name="android.permission.CONTROL_VPN" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 68f9cb05ecaf..8e7ffdfd4b47 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -16,8 +16,10 @@
package com.android.systemui.statusbar;
+import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -33,12 +35,14 @@ import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.drawable.Icon;
import android.os.UserHandle;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.NotificationColorUtil;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -100,4 +104,17 @@ public class StatusBarIconViewTest extends SysuiTestCase {
assertFalse(mIconView.set(mStatusBarIcon));
}
+
+ @Test
+ public void testGetContrastedStaticDrawableColor() {
+ mIconView.setStaticDrawableColor(Color.DKGRAY);
+ int color = mIconView.getContrastedStaticDrawableColor(Color.WHITE);
+ assertEquals("Color should not change when we have enough contrast",
+ Color.DKGRAY, color);
+
+ mIconView.setStaticDrawableColor(Color.WHITE);
+ color = mIconView.getContrastedStaticDrawableColor(Color.WHITE);
+ assertTrue("Similar colors should be shifted to satisfy contrast",
+ NotificationColorUtil.satisfiesTextContrast(Color.WHITE, color));
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 0e3ea7a07e7d..17ca92458bcf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -38,6 +38,8 @@ import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import android.app.Notification;
+import android.app.trust.TrustManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.HandlerThread;
@@ -55,6 +57,7 @@ import android.testing.TestableLooper;
import android.testing.TestableLooper.MessageHandler;
import android.testing.TestableLooper.RunWithLooper;
import android.util.DisplayMetrics;
+import android.view.ViewGroup.LayoutParams;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -75,6 +78,8 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
import java.util.ArrayList;
@SmallTest
@@ -99,6 +104,8 @@ public class StatusBarTest extends SysuiTestCase {
@Before
public void setup() throws Exception {
+ mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
+ mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
mUnlockMethodCache = mock(UnlockMethodCache.class);
mKeyguardIndicationController = mock(KeyguardIndicationController.class);
@@ -108,6 +115,7 @@ public class StatusBarTest extends SysuiTestCase {
mNotificationData = mock(NotificationData.class);
mSystemServicesProxy = mock(SystemServicesProxy.class);
mNotificationPanelView = mock(NotificationPanelView.class);
+ when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
mNotificationList = mock(ArrayList.class);
IPowerManager powerManagerService = mock(IPowerManager.class);
HandlerThread handlerThread = new HandlerThread("TestThread");
@@ -122,6 +130,7 @@ public class StatusBarTest extends SysuiTestCase {
mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
mNotificationData, mPowerManager, mSystemServicesProxy, mNotificationPanelView,
mBarService);
+ mStatusBar.mContext = mContext;
doAnswer(invocation -> {
OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
onDismissAction.onDismiss();
@@ -385,6 +394,11 @@ public class StatusBarTest extends SysuiTestCase {
TestableLooper.get(this).processAllMessages();
}
+ @Test
+ public void testDump_DoesNotCrash() {
+ mStatusBar.dump(null, new PrintWriter(new ByteArrayOutputStream()), null);
+ }
+
static class TestableStatusBar extends StatusBar {
public TestableStatusBar(StatusBarKeyguardViewManager man,
UnlockMethodCache unlock, KeyguardIndicationController key,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
new file mode 100644
index 000000000000..a10bebfd4f2d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.location.LocationManager;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class LocationControllerImplTest extends SysuiTestCase {
+
+ private LocationControllerImpl mLocationController;
+
+ @Before
+ public void setup() {
+ mLocationController = spy(new LocationControllerImpl(mContext,
+ TestableLooper.get(this).getLooper()));
+ }
+
+ @Test
+ public void testRemoveSelfActive_DoesNotCrash() {
+ LocationController.LocationChangeCallback callback = new LocationChangeCallback() {
+ @Override
+ public void onLocationActiveChanged(boolean active) {
+ mLocationController.removeCallback(this);
+ }
+ };
+ mLocationController.addCallback(callback);
+ mLocationController.addCallback(mock(LocationChangeCallback.class));
+
+ when(mLocationController.areActiveHighPowerLocationRequests()).thenReturn(false);
+ mLocationController.onReceive(mContext, new Intent(
+ LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION));
+ when(mLocationController.areActiveHighPowerLocationRequests()).thenReturn(true);
+ mLocationController.onReceive(mContext, new Intent(
+ LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION));
+
+ TestableLooper.get(this).processAllMessages();
+ }
+
+ @Test
+ public void testRemoveSelfSettings_DoesNotCrash() {
+ LocationController.LocationChangeCallback callback = new LocationChangeCallback() {
+ @Override
+ public void onLocationSettingsChanged(boolean isEnabled) {
+ mLocationController.removeCallback(this);
+ }
+ };
+ mLocationController.addCallback(callback);
+ mLocationController.addCallback(mock(LocationChangeCallback.class));
+
+ TestableLooper.get(this).processAllMessages();
+ }
+} \ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index f696f94cae1f..b3a4007ff399 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4124,6 +4124,16 @@ message MetricsEvent {
// OS: O DR
ACTION_PSD_LOADER = 1019;
+ // ACTION: Background check action on an app
+ // CATEGORY: SETTINGS
+ // OS: O DR
+ ACTION_APP_BACKGROUND_CHECK = 1020;
+
+ // ACTION: Location check action on an app
+ // CATEGORY: SETTINGS
+ // OS: O DR
+ ACTION_APP_LOCATION_CHECK = 1021;
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index e85f96be3160..71f699c8da54 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -270,6 +270,12 @@ public final class AutofillManagerService extends SystemService {
}
@Override
+ public void onSwitchUser(int userHandle) {
+ if (sDebug) Slog.d(TAG, "Hiding UI when user switched");
+ mUi.hideAll(null);
+ }
+
+ @Override
public void onCleanupUser(int userId) {
synchronized (mLock) {
removeCachedServiceLocked(userId);
@@ -458,6 +464,7 @@ public final class AutofillManagerService extends SystemService {
private void updateCachedServiceLocked(int userId, boolean disabled) {
AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
if (service != null) {
+ service.destroySessionsLocked();
service.updateLocked(disabled);
if (!service.isEnabled()) {
removeCachedServiceLocked(userId);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 1a02e8d8eb97..751c0547afd6 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -360,8 +360,7 @@ final class AutofillManagerServiceImpl {
}
void disableOwnedAutofillServicesLocked(int uid) {
- if (mInfo == null || mInfo.getServiceInfo().applicationInfo.uid
- != UserHandle.getAppId(uid)) {
+ if (mInfo == null || mInfo.getServiceInfo().applicationInfo.uid != uid) {
return;
}
final long identity = Binder.clearCallingIdentity();
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index d1fbbf9ceda1..c9e2a928dee0 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -191,6 +191,7 @@ final class SaveUi {
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
+ window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS);
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
window.setGravity(Gravity.BOTTOM | Gravity.CENTER);
window.setCloseOnTouchOutside(true);
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 72754616133a..eda283e82d79 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -324,58 +324,13 @@ public class LocationManagerService extends ILocationManager.Stub {
ActivityManager.OnUidImportanceListener uidImportanceListener
= new ActivityManager.OnUidImportanceListener() {
@Override
- public void onUidImportance(int uid, int importance) {
- boolean foreground = isImportanceForeground(importance);
- HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size());
- synchronized (mLock) {
- for (Entry<String, ArrayList<UpdateRecord>> entry
- : mRecordsByProvider.entrySet()) {
- String provider = entry.getKey();
- for (UpdateRecord record : entry.getValue()) {
- if (record.mReceiver.mIdentity.mUid == uid
- && record.mIsForegroundUid != foreground) {
- if (D) Log.d(TAG, "request from uid " + uid + " is now "
- + (foreground ? "foreground" : "background)"));
- record.mIsForegroundUid = foreground;
-
- if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
- affectedProviders.add(provider);
- }
- }
- }
- }
- for (String provider : affectedProviders) {
- applyRequirementsLocked(provider);
- }
-
- for (Entry<IGnssMeasurementsListener, Identity> entry
- : mGnssMeasurementsListeners.entrySet()) {
- if (entry.getValue().mUid == uid) {
- if (D) Log.d(TAG, "gnss measurements listener from uid " + uid
- + " is now " + (foreground ? "foreground" : "background)"));
- if (foreground || isThrottlingExemptLocked(entry.getValue())) {
- mGnssMeasurementsProvider.addListener(entry.getKey());
- } else {
- mGnssMeasurementsProvider.removeListener(entry.getKey());
- }
- }
- }
-
- for (Entry<IGnssNavigationMessageListener, Identity> entry
- : mGnssNavigationMessageListeners.entrySet()) {
- if (entry.getValue().mUid == uid) {
- if (D) Log.d(TAG, "gnss navigation message listener from uid "
- + uid + " is now "
- + (foreground ? "foreground" : "background)"));
- if (foreground || isThrottlingExemptLocked(entry.getValue())) {
- mGnssNavigationMessageProvider.addListener(entry.getKey());
- } else {
- mGnssNavigationMessageProvider.removeListener(entry.getKey());
- }
- }
+ public void onUidImportance(final int uid, final int importance) {
+ mLocationHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ onUidImportanceChanged(uid, importance);
}
- }
-
+ });
}
};
mActivityManager.addOnUidImportanceListener(uidImportanceListener,
@@ -455,6 +410,59 @@ public class LocationManagerService extends ILocationManager.Stub {
}, UserHandle.ALL, intentFilter, null, mLocationHandler);
}
+ private void onUidImportanceChanged(int uid, int importance) {
+ boolean foreground = isImportanceForeground(importance);
+ HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size());
+ synchronized (mLock) {
+ for (Entry<String, ArrayList<UpdateRecord>> entry
+ : mRecordsByProvider.entrySet()) {
+ String provider = entry.getKey();
+ for (UpdateRecord record : entry.getValue()) {
+ if (record.mReceiver.mIdentity.mUid == uid
+ && record.mIsForegroundUid != foreground) {
+ if (D) Log.d(TAG, "request from uid " + uid + " is now "
+ + (foreground ? "foreground" : "background)"));
+ record.mIsForegroundUid = foreground;
+
+ if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
+ affectedProviders.add(provider);
+ }
+ }
+ }
+ }
+ for (String provider : affectedProviders) {
+ applyRequirementsLocked(provider);
+ }
+
+ for (Entry<IGnssMeasurementsListener, Identity> entry
+ : mGnssMeasurementsListeners.entrySet()) {
+ if (entry.getValue().mUid == uid) {
+ if (D) Log.d(TAG, "gnss measurements listener from uid " + uid
+ + " is now " + (foreground ? "foreground" : "background)"));
+ if (foreground || isThrottlingExemptLocked(entry.getValue())) {
+ mGnssMeasurementsProvider.addListener(entry.getKey());
+ } else {
+ mGnssMeasurementsProvider.removeListener(entry.getKey());
+ }
+ }
+ }
+
+ for (Entry<IGnssNavigationMessageListener, Identity> entry
+ : mGnssNavigationMessageListeners.entrySet()) {
+ if (entry.getValue().mUid == uid) {
+ if (D) Log.d(TAG, "gnss navigation message listener from uid "
+ + uid + " is now "
+ + (foreground ? "foreground" : "background)"));
+ if (foreground || isThrottlingExemptLocked(entry.getValue())) {
+ mGnssNavigationMessageProvider.addListener(entry.getKey());
+ } else {
+ mGnssNavigationMessageProvider.removeListener(entry.getKey());
+ }
+ }
+ }
+ }
+ }
+
private static boolean isImportanceForeground(int importance) {
return importance <= FOREGROUND_IMPORTANCE_CUTOFF;
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 86c8909942ac..8ea334dbfb17 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1058,6 +1058,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
@Override
+ public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException {
+ try {
+ mNetdService.setIPv6AddrGenMode(iface, mode);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ @Override
public void disableIpv6(String iface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 3948ee1c3d1a..a54fe727f57e 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -162,7 +162,8 @@ public class AccountManagerService
@Override
public void onStopUser(int userHandle) {
- mService.onStopUser(userHandle);
+ Slog.i(TAG, "onStopUser " + userHandle);
+ mService.purgeUserData(userHandle);
}
}
@@ -314,6 +315,21 @@ public class AccountManagerService
injector.addLocalService(new AccountManagerInternalImpl());
+ IntentFilter userFilter = new IntentFilter();
+ userFilter.addAction(Intent.ACTION_USER_REMOVED);
+ mContext.registerReceiverAsUser(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_REMOVED.equals(action)) {
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ if (userId < 1) return;
+ Slog.i(TAG, "User " + userId + " removed");
+ purgeUserData(userId);
+ }
+ }
+ }, UserHandle.ALL, userFilter, null, null);
+
// Need to cancel account request notifications if the update/install can access the account
new PackageMonitor() {
@Override
@@ -1360,9 +1376,7 @@ public class AccountManagerService
}
}
-
- private void onStopUser(int userId) {
- Log.i(TAG, "onStopUser " + userId);
+ private void purgeUserData(int userId) {
UserAccounts accounts;
synchronized (mUsers) {
accounts = mUsers.get(userId);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e5ab784df882..c6307a793e34 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -706,6 +706,8 @@ public class AudioService extends IAudioService.Stub
mMediaFocusControl = new MediaFocusControl(mContext, mPlaybackMonitor);
+ mRecordMonitor = new RecordingActivityMonitor(mContext);
+
readAndSetLowRamDevice();
// Call setRingerModeInt() to apply correct mute
@@ -6309,6 +6311,8 @@ public class AudioService extends IAudioService.Stub
dumpAudioPolicies(pw);
mPlaybackMonitor.dump(pw);
+
+ mRecordMonitor.dump(pw);
}
private static String safeMediaVolumeStateToString(Integer state) {
@@ -6730,10 +6734,13 @@ public class AudioService extends IAudioService.Stub
//======================
// Audio policy callbacks from AudioSystem for recording configuration updates
//======================
- private final RecordingActivityMonitor mRecordMonitor = new RecordingActivityMonitor();
+ private final RecordingActivityMonitor mRecordMonitor;
public void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
- mRecordMonitor.registerRecordingCallback(rcdb);
+ final boolean isPrivileged =
+ (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
+ android.Manifest.permission.MODIFY_AUDIO_ROUTING));
+ mRecordMonitor.registerRecordingCallback(rcdb, isPrivileged);
}
public void unregisterRecordingCallback(IRecordingConfigDispatcher rcdb) {
@@ -6741,7 +6748,10 @@ public class AudioService extends IAudioService.Stub
}
public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
- return mRecordMonitor.getActiveRecordingConfigurations();
+ final boolean isPrivileged =
+ (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
+ android.Manifest.permission.MODIFY_AUDIO_ROUTING));
+ return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
}
public void disableRingtoneSync(final int userId) {
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index 57d55de8d002..34309b62d2f7 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -16,8 +16,11 @@
package com.android.server.audio;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
import android.media.AudioRecordingConfiguration;
import android.media.AudioSystem;
import android.media.IRecordingConfigDispatcher;
@@ -26,7 +29,10 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
+import java.io.PrintWriter;
+import java.text.DateFormat;
import java.util.ArrayList;
+import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -39,31 +45,47 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
public final static String TAG = "AudioService.RecordingActivityMonitor";
private ArrayList<RecMonitorClient> mClients = new ArrayList<RecMonitorClient>();
+ // a public client is one that needs an anonymized version of the playback configurations, we
+ // keep track of whether there is at least one to know when we need to create the list of
+ // playback configurations that do not contain uid/package name information.
+ private boolean mHasPublicClients = false;
private HashMap<Integer, AudioRecordingConfiguration> mRecordConfigs =
new HashMap<Integer, AudioRecordingConfiguration>();
- RecordingActivityMonitor() {
+ private final PackageManager mPackMan;
+
+ RecordingActivityMonitor(Context ctxt) {
RecMonitorClient.sMonitor = this;
+ mPackMan = ctxt.getPackageManager();
}
/**
* Implementation of android.media.AudioSystem.AudioRecordingCallback
*/
- public void onRecordingConfigurationChanged(int event, int session, int source,
- int[] recordingInfo) {
+ public void onRecordingConfigurationChanged(int event, int uid, int session, int source,
+ int[] recordingInfo, String packName) {
if (MediaRecorder.isSystemOnlyAudioSource(source)) {
return;
}
- final List<AudioRecordingConfiguration> configs =
- updateSnapshot(event, session, source, recordingInfo);
- if (configs != null){
- synchronized(mClients) {
+ final List<AudioRecordingConfiguration> configsSystem =
+ updateSnapshot(event, uid, session, source, recordingInfo);
+ if (configsSystem != null){
+ synchronized (mClients) {
+ // list of recording configurations for "public consumption". It is only computed if
+ // there are non-system recording activity listeners.
+ final List<AudioRecordingConfiguration> configsPublic = mHasPublicClients ?
+ anonymizeForPublicConsumption(configsSystem) :
+ new ArrayList<AudioRecordingConfiguration>();
final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
while (clientIterator.hasNext()) {
+ final RecMonitorClient rmc = clientIterator.next();
try {
- clientIterator.next().mDispatcherCb.dispatchRecordingConfigChange(
- configs);
+ if (rmc.mIsPrivileged) {
+ rmc.mDispatcherCb.dispatchRecordingConfigChange(configsSystem);
+ } else {
+ rmc.mDispatcherCb.dispatchRecordingConfigChange(configsPublic);
+ }
} catch (RemoteException e) {
Log.w(TAG, "Could not call dispatchRecordingConfigChange() on client", e);
}
@@ -72,17 +94,42 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
}
}
+ protected void dump(PrintWriter pw) {
+ // players
+ pw.println("\nRecordActivityMonitor dump time: "
+ + DateFormat.getTimeInstance().format(new Date()));
+ synchronized(mRecordConfigs) {
+ for (AudioRecordingConfiguration conf : mRecordConfigs.values()) {
+ conf.dump(pw);
+ }
+ }
+ }
+
+ private ArrayList<AudioRecordingConfiguration> anonymizeForPublicConsumption(
+ List<AudioRecordingConfiguration> sysConfigs) {
+ ArrayList<AudioRecordingConfiguration> publicConfigs =
+ new ArrayList<AudioRecordingConfiguration>();
+ // only add active anonymized configurations,
+ for (AudioRecordingConfiguration config : sysConfigs) {
+ publicConfigs.add(AudioRecordingConfiguration.anonymizedCopy(config));
+ }
+ return publicConfigs;
+ }
+
void initMonitor() {
AudioSystem.setRecordingCallback(this);
}
- void registerRecordingCallback(IRecordingConfigDispatcher rcdb) {
+ void registerRecordingCallback(IRecordingConfigDispatcher rcdb, boolean isPrivileged) {
if (rcdb == null) {
return;
}
- synchronized(mClients) {
- final RecMonitorClient rmc = new RecMonitorClient(rcdb);
+ synchronized (mClients) {
+ final RecMonitorClient rmc = new RecMonitorClient(rcdb, isPrivileged);
if (rmc.init()) {
+ if (!isPrivileged) {
+ mHasPublicClients = true;
+ }
mClients.add(rmc);
}
}
@@ -92,22 +139,34 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
if (rcdb == null) {
return;
}
- synchronized(mClients) {
+ synchronized (mClients) {
final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
+ boolean hasPublicClients = false;
while (clientIterator.hasNext()) {
RecMonitorClient rmc = clientIterator.next();
if (rcdb.equals(rmc.mDispatcherCb)) {
rmc.release();
clientIterator.remove();
- break;
+ } else {
+ if (!rmc.mIsPrivileged) {
+ hasPublicClients = true;
+ }
}
}
+ mHasPublicClients = hasPublicClients;
}
}
- List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
+ List<AudioRecordingConfiguration> getActiveRecordingConfigurations(boolean isPrivileged) {
synchronized(mRecordConfigs) {
- return new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values());
+ if (isPrivileged) {
+ return new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values());
+ } else {
+ final List<AudioRecordingConfiguration> configsPublic =
+ anonymizeForPublicConsumption(
+ new ArrayList<AudioRecordingConfiguration>(mRecordConfigs.values()));
+ return configsPublic;
+ }
}
}
@@ -122,8 +181,8 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
* @return null if the list of active recording sessions has not been modified, a list
* with the current active configurations otherwise.
*/
- private List<AudioRecordingConfiguration> updateSnapshot(int event, int session, int source,
- int[] recordingInfo) {
+ private List<AudioRecordingConfiguration> updateSnapshot(int event, int uid, int session,
+ int source, int[] recordingInfo) {
final boolean configChanged;
final ArrayList<AudioRecordingConfiguration> configs;
synchronized(mRecordConfigs) {
@@ -147,10 +206,19 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
.build();
final int patchHandle = recordingInfo[6];
final Integer sessionKey = new Integer(session);
+
+ final String[] packages = mPackMan.getPackagesForUid(uid);
+ final String packageName;
+ if (packages != null && packages.length > 0) {
+ packageName = packages[0];
+ } else {
+ packageName = "";
+ }
+ final AudioRecordingConfiguration updatedConfig =
+ new AudioRecordingConfiguration(uid, session, source,
+ clientFormat, deviceFormat, patchHandle, packageName);
+
if (mRecordConfigs.containsKey(sessionKey)) {
- final AudioRecordingConfiguration updatedConfig =
- new AudioRecordingConfiguration(session, source,
- clientFormat, deviceFormat, patchHandle);
if (updatedConfig.equals(mRecordConfigs.get(sessionKey))) {
configChanged = false;
} else {
@@ -160,9 +228,7 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
configChanged = true;
}
} else {
- mRecordConfigs.put(sessionKey,
- new AudioRecordingConfiguration(session, source,
- clientFormat, deviceFormat, patchHandle));
+ mRecordConfigs.put(sessionKey, updatedConfig);
configChanged = true;
}
break;
@@ -189,9 +255,11 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
static RecordingActivityMonitor sMonitor;
final IRecordingConfigDispatcher mDispatcherCb;
+ final boolean mIsPrivileged;
- RecMonitorClient(IRecordingConfigDispatcher rcdb) {
+ RecMonitorClient(IRecordingConfigDispatcher rcdb, boolean isPrivileged) {
mDispatcherCb = rcdb;
+ mIsPrivileged = isPrivileged;
}
public void binderDied() {
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 4a45c074f4d1..da7572274497 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -466,6 +466,11 @@ public class GnssLocationProvider implements LocationProviderInterface {
// Always on, notify HAL so it can get data it needs
sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
}
+
+ @Override
+ public void onLost(Network network) {
+ sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
+ }
};
/**
@@ -802,11 +807,21 @@ public class GnssLocationProvider implements LocationProviderInterface {
private void handleUpdateNetworkState(Network network) {
// retrieve NetworkInfo for this UID
NetworkInfo info = mConnMgr.getNetworkInfo(network);
- if (info == null) {
- return;
+
+ boolean networkAvailable = false;
+ boolean isConnected = false;
+ int type = ConnectivityManager.TYPE_NONE;
+ boolean isRoaming = false;
+ String apnName = null;
+
+ if (info != null) {
+ networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
+ isConnected = info.isConnected();
+ type = info.getType();
+ isRoaming = info.isRoaming();
+ apnName = info.getExtraInfo();
}
- boolean isConnected = info.isConnected();
if (DEBUG) {
String message = String.format(
"UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
@@ -818,8 +833,6 @@ public class GnssLocationProvider implements LocationProviderInterface {
}
if (native_is_agps_ril_supported()) {
- boolean dataEnabled = TelephonyManager.getDefault().getDataEnabled();
- boolean networkAvailable = info.isAvailable() && dataEnabled;
String defaultApn = getSelectedApn();
if (defaultApn == null) {
defaultApn = "dummy-apn";
@@ -827,10 +840,10 @@ public class GnssLocationProvider implements LocationProviderInterface {
native_update_network_state(
isConnected,
- info.getType(),
- info.isRoaming(),
+ type,
+ isRoaming,
networkAvailable,
- info.getExtraInfo(),
+ apnName,
defaultApn);
} else if (DEBUG) {
Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not supported");
@@ -838,7 +851,6 @@ public class GnssLocationProvider implements LocationProviderInterface {
if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
if (isConnected) {
- String apnName = info.getExtraInfo();
if (apnName == null) {
// assign a dummy value in the case of C2K as otherwise we will have a runtime
// exception in the following call to native_agps_data_conn_open
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2ac7e5043518..c1c14e8a2cef 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1057,14 +1057,12 @@ public class PackageManagerService extends IPackageManager.Stub
scheduleWriteSettingsLocked();
}
}
- sendVerificationRequest(userId, verificationId, ivs);
+ sendVerificationRequest(verificationId, ivs);
}
mCurrentIntentFilterVerifications.clear();
}
- private void sendVerificationRequest(int userId, int verificationId,
- IntentFilterVerificationState ivs) {
-
+ private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
verificationIntent.putExtra(
PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
@@ -1084,10 +1082,9 @@ public class PackageManagerService extends IPackageManager.Stub
DeviceIdleController.LocalService idleController = getDeviceIdleController();
idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
- userId, false, "intent filter verifier");
+ UserHandle.USER_SYSTEM, true, "intent filter verifier");
- UserHandle user = new UserHandle(userId);
- mContext.sendBroadcastAsUser(verificationIntent, user);
+ mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
"Sending IntentFilter verification broadcast");
}
@@ -7178,16 +7175,13 @@ public class PackageManagerService extends IPackageManager.Stub
*/
private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
String ephemeralPkgName) {
- // TODO: When adding on-demand split support for non-instant apps, remove this check
- // and always apply post filtering
- if (ephemeralPkgName == null) {
- return resolveInfos;
- }
for (int i = resolveInfos.size() - 1; i >= 0; i--) {
final ResolveInfo info = resolveInfos.get(i);
final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
+ // TODO: When adding on-demand split support for non-instant apps, remove this check
+ // and always apply post filtering
// allow activities that are defined in the provided package
- if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
+ if (isEphemeralApp) {
if (info.activityInfo.splitName != null
&& !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
info.activityInfo.splitName)) {
@@ -7212,6 +7206,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
continue;
}
+ // caller is a full app, don't need to apply any other filtering
+ if (ephemeralPkgName == null) {
+ continue;
+ }
// allow activities that have been explicitly exposed to ephemeral apps
if (!isEphemeralApp
&& ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5c6521b1a8b6..89dbc2a1c1c4 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -23,6 +23,7 @@ import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.AppOpsManager.OP_TOAST_WINDOW;
+import static android.content.Context.CONTEXT_RESTRICTED;
import static android.content.Context.DISPLAY_SERVICE;
import static android.content.Context.WINDOW_SERVICE;
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
@@ -2823,7 +2824,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (theme != context.getThemeResId() || labelRes != 0) {
try {
- context = context.createPackageContext(packageName, 0);
+ context = context.createPackageContext(packageName, CONTEXT_RESTRICTED);
context.setTheme(theme);
} catch (PackageManager.NameNotFoundException e) {
// Ignore
diff --git a/services/core/java/com/android/server/radio/RadioService.java b/services/core/java/com/android/server/radio/RadioService.java
index 87a6fc1ea5ce..8b0d3aa44ac0 100644
--- a/services/core/java/com/android/server/radio/RadioService.java
+++ b/services/core/java/com/android/server/radio/RadioService.java
@@ -24,16 +24,12 @@ import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
import android.os.ParcelableException;
-import android.util.Slog;
import com.android.server.SystemService;
import java.util.List;
public class RadioService extends SystemService {
- // TODO(b/36863239): rename to RadioService when native service goes away
- private static final String TAG = "RadioServiceJava";
-
private final RadioServiceImpl mServiceImpl = new RadioServiceImpl();
/**
@@ -63,7 +59,6 @@ public class RadioService extends SystemService {
@Override
public void onStart() {
publishBinderService(Context.RADIO_SERVICE, mServiceImpl);
- Slog.v(TAG, "RadioService started");
}
private class RadioServiceImpl extends IRadioService.Stub {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 2d7fc6883292..6b514552b227 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -427,8 +427,9 @@ public class DockedStackDividerController implements DimLayerUser {
inputMethodManagerInternal.hideCurrentInputMethod();
mImeHideRequested = true;
}
+ return;
}
- setMinimizedDockedStack(false, false /* animate */);
+ setMinimizedDockedStack(false /* minimizedDock */, false /* animate */);
}
/**
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 091e1cba43a2..22b0f5bcdf07 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
@@ -37,6 +38,7 @@ import android.os.Parcel;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.Trace;
import android.os.UserHandle;
import android.util.MergedConfiguration;
import android.util.Slog;
@@ -85,6 +87,7 @@ public class Session extends IWindowSession.Stub
private boolean mClientDead = false;
private float mLastReportedAnimatorScale;
private String mPackageName;
+ private String mRelayoutTag;
public Session(WindowManagerService service, IWindowSessionCallback callback,
IInputMethodClient client, IInputContext inputContext) {
@@ -224,10 +227,12 @@ public class Session extends IWindowSession.Stub
MergedConfiguration mergedConfiguration, Surface outSurface) {
if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
outStableInsets, outsets, outBackdropFrame, mergedConfiguration, outSurface);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
@@ -575,6 +580,7 @@ public class Session extends IWindowSession.Stub
void windowAddedLocked(String packageName) {
mPackageName = packageName;
+ mRelayoutTag = "relayoutWindow: " + mPackageName;
if (mSurfaceSession == null) {
if (WindowManagerService.localLOGV) Slog.v(
TAG_WM, "First window added to " + this + ", creating SurfaceSession");
@@ -698,6 +704,7 @@ public class Session extends IWindowSession.Stub
pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces);
pw.print(" mClientDead="); pw.print(mClientDead);
pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
+ pw.print(prefix); pw.print("mPackageName="); pw.println(mPackageName);
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0c2ca859a31f..f9d7c3704341 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -30,6 +30,7 @@ import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.os.Process.myPid;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.os.UserHandle.USER_NULL;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -892,11 +893,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
void openSurfaceTransaction() {
- synchronized (mWindowMap) {
- if (mRoot.mSurfaceTraceEnabled) {
- mRoot.mRemoteEventTrace.openSurfaceTransaction();
+ try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
+ synchronized (mWindowMap) {
+ if (mRoot.mSurfaceTraceEnabled) {
+ mRoot.mRemoteEventTrace.openSurfaceTransaction();
+ }
+ SurfaceControl.openTransaction();
}
- SurfaceControl.openTransaction();
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
@@ -912,16 +918,21 @@ public class WindowManagerService extends IWindowManager.Stub
* blocks and we call it repeatedly, like we do for animations.
*/
void closeSurfaceTransaction(boolean withLockHeld) {
- synchronized (mWindowMap) {
- if (mRoot.mSurfaceTraceEnabled) {
- mRoot.mRemoteEventTrace.closeSurfaceTransaction();
+ try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
+ synchronized (mWindowMap) {
+ if (mRoot.mSurfaceTraceEnabled) {
+ mRoot.mRemoteEventTrace.closeSurfaceTransaction();
+ }
+ if (withLockHeld) {
+ SurfaceControl.closeTransaction();
+ }
}
- if (withLockHeld) {
+ if (!withLockHeld) {
SurfaceControl.closeTransaction();
}
- }
- if (!withLockHeld) {
- SurfaceControl.closeTransaction();
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
@@ -1996,6 +2007,8 @@ public class WindowManagerService extends IWindowManager.Stub
(win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
|| !win.mAppToken.isClientHidden())) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");
+
// We are about to create a surface, but we didn't run a layout yet. So better run
// a layout now that we already know the right size, as a resize call will make the
// surface transaction blocking until next vsync and slow us down.
@@ -2007,6 +2020,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges,
oldVisibility);
+
try {
result = createSurfaceControl(outSurface, result, win, winAnimator);
} catch (Exception e) {
@@ -2026,7 +2040,10 @@ public class WindowManagerService extends IWindowManager.Stub
imMayMove = true;
}
win.adjustStartingWindowFlags();
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} else {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_2");
+
winAnimator.mEnterAnimationPending = false;
winAnimator.mEnteringAnimation = false;
final boolean usingSavedSurfaceBeforeVisible =
@@ -2061,18 +2078,22 @@ public class WindowManagerService extends IWindowManager.Stub
// We already told the client to go invisible, but the message may not be
// handled yet, or it might want to draw a last frame. If we already have a
// surface, let the client use that, but don't create new surface at this point.
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
winAnimator.mSurfaceController.getSurface(outSurface);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} else {
if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
try {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
+ win.mAttrs.getTitle());
outSurface.release();
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
+
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
if (focusMayChange) {
@@ -2109,8 +2130,11 @@ public class WindowManagerService extends IWindowManager.Stub
}
win.setDisplayLayoutNeeded();
- win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
+ win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+ "relayoutWindow: updateOrientationFromAppTokens");
configChanged = updateOrientationFromAppTokensLocked(false, displayId);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
// We may be deferring layout passes at the moment, but since the client is interested
// in the new out values right now we need to force a layout.
@@ -2163,7 +2187,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (configChanged) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: sendNewConfiguration");
sendNewConfiguration(displayId);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
Binder.restoreCallingIdentity(origId);
return result;
@@ -2224,8 +2250,14 @@ public class WindowManagerService extends IWindowManager.Stub
if (!win.mHasSurface) {
result |= RELAYOUT_RES_SURFACE_CHANGED;
}
- WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked(
- win.mAttrs.type, win.mOwnerUid);
+
+ WindowSurfaceController surfaceController;
+ try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
+ surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
if (surfaceController != null) {
surfaceController.getSurface(outSurface);
if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurface + ": copied");
@@ -2235,6 +2267,7 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG_WM, "Failed to create surface control for " + win);
outSurface.release();
}
+
return result;
}
@@ -2281,7 +2314,7 @@ public class WindowManagerService extends IWindowManager.Stub
// frozen, there is no reason to animate and it can cause strange
// artifacts when we unfreeze the display if some different animation
// is running.
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WM#applyAnimationLocked");
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WM#applyAnimationLocked");
if (okToDisplay()) {
final DisplayContent displayContent = atoken.getTask().getDisplayContent();
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
@@ -2337,7 +2370,7 @@ public class WindowManagerService extends IWindowManager.Stub
} else {
atoken.mAppAnimator.clearAnimation();
}
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return atoken.mAppAnimator.animation != null;
}
@@ -3424,7 +3457,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (!mBootAnimationStopped) {
// Do this one time.
- Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
+ Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
try {
IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
if (surfaceFlinger != null) {
@@ -3447,7 +3480,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
- Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
+ Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
mDisplayEnabled = true;
if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, "******************** ENABLING SCREEN!");
@@ -3678,12 +3711,12 @@ public class WindowManagerService extends IWindowManager.Stub
throw new SecurityException("Requires READ_FRAME_BUFFER permission");
}
try {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
return screenshotApplications(null /* appToken */, DEFAULT_DISPLAY, -1 /* width */,
-1 /* height */, true /* includeFullDisplay */, 1f /* frameScale */,
Bitmap.Config.ARGB_8888, true /* wallpaperOnly */, false /* includeDecor */);
} finally {
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
@@ -3869,6 +3902,8 @@ public class WindowManagerService extends IWindowManager.Stub
+ " alwaysSendConfiguration=" + alwaysSendConfiguration
+ " forceRelayout=" + forceRelayout);
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation");
+
long origId = Binder.clearCallingIdentity();
try {
@@ -3877,20 +3912,28 @@ public class WindowManagerService extends IWindowManager.Stub
final int displayId;
synchronized (mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
rotationChanged = displayContent.updateRotationUnchecked(
false /* inTransaction */);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
if (!rotationChanged || forceRelayout) {
displayContent.setLayoutNeeded();
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
+ "updateRotation: performSurfacePlacement");
mWindowPlacerLocked.performSurfacePlacement();
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
displayId = displayContent.getDisplayId();
}
if (rotationChanged || alwaysSendConfiguration) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: sendNewConfiguration");
sendNewConfiguration(displayId);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
} finally {
Binder.restoreCallingIdentity(origId);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
@@ -5855,7 +5898,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
WindowState newFocus = mRoot.computeFocusedWindow();
if (mCurrentFocus != newFocus) {
- Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
// This check makes sure that we don't already have the focus
// change message pending.
mH.removeMessages(H.REPORT_FOCUS_CHANGE);
@@ -5931,7 +5974,7 @@ public class WindowManagerService extends IWindowManager.Stub
// other apps' UI.
displayContent.scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
- Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
return true;
}
return false;
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index edbdf8bc5ed9..27927e6c0693 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
@@ -33,6 +34,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.os.IBinder;
import android.os.Debug;
+import android.os.Trace;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
@@ -101,8 +103,10 @@ class WindowSurfaceController {
mSurfaceControl = new SurfaceTrace(
s, name, w, h, format, flags, windowType, ownerUid);
} else {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
mSurfaceControl = new SurfaceControl(
s, name, w, h, format, flags, windowType, ownerUid);
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
if (mService.mRoot.mSurfaceTraceEnabled) {
diff --git a/services/core/jni/com_android_server_radio_RadioService.cpp b/services/core/jni/com_android_server_radio_RadioService.cpp
index 2e0fbfd40ede..fa64901caee9 100644
--- a/services/core/jni/com_android_server_radio_RadioService.cpp
+++ b/services/core/jni/com_android_server_radio_RadioService.cpp
@@ -199,10 +199,10 @@ static jobject nativeOpenTuner(JNIEnv *env, jobject obj, long nativeContext, jin
HalRevision halRev;
if (V1_1::IBroadcastRadio::castFrom(module).withDefault(nullptr) != nullptr) {
- ALOGI("Opening tuner with broadcast radio HAL 1.1");
+ ALOGI("Opening tuner %d with broadcast radio HAL 1.1", moduleId);
halRev = HalRevision::V1_1;
} else {
- ALOGI("Opening tuner with broadcast radio HAL 1.0");
+ ALOGI("Opening tuner %d with broadcast radio HAL 1.0", moduleId);
halRev = HalRevision::V1_0;
}
@@ -233,7 +233,7 @@ static jobject nativeOpenTuner(JNIEnv *env, jobject obj, long nativeContext, jin
}
Tuner::setHalTuner(env, tuner, halTuner);
- ALOGI("Opened tuner %p", halTuner.get());
+ ALOGD("Opened tuner %p", halTuner.get());
return tuner.release();
}
diff --git a/services/core/jni/com_android_server_radio_Tuner.cpp b/services/core/jni/com_android_server_radio_Tuner.cpp
index f9418e4c108e..4b6f30b1c09f 100644
--- a/services/core/jni/com_android_server_radio_Tuner.cpp
+++ b/services/core/jni/com_android_server_radio_Tuner.cpp
@@ -150,7 +150,7 @@ void setHalTuner(JNIEnv *env, JavaRef<jobject> const &jTuner, sp<V1_0::ITuner> h
auto& ctx = getNativeContext(env, jTuner);
if (ctx.mIsClosed) {
- ALOGI("Tuner was closed during initialization");
+ ALOGD("Tuner was closed during initialization");
// dropping the last reference will close HAL tuner
return;
}
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index ede2b3ae01ec..f09ec6e660bd 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -20,16 +20,17 @@ import com.android.internal.util.MessageUtils;
import com.android.internal.util.WakeupMessage;
import android.content.Context;
-import android.net.apf.ApfCapabilities;
-import android.net.apf.ApfFilter;
import android.net.DhcpResults;
+import android.net.INetd;
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
-import android.net.LinkProperties;
import android.net.LinkProperties.ProvisioningChange;
+import android.net.LinkProperties;
import android.net.ProxyInfo;
import android.net.RouteInfo;
import android.net.StaticIpConfiguration;
+import android.net.apf.ApfCapabilities;
+import android.net.apf.ApfFilter;
import android.net.dhcp.DhcpClient;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpManagerEvent;
@@ -38,7 +39,9 @@ import android.os.INetworkManagementService;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.os.SystemClock;
+import android.system.OsConstants;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
@@ -319,6 +322,16 @@ public class IpManager extends StateMachine {
return this;
}
+ public Builder withIPv6AddrGenModeEUI64() {
+ mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_EUI64;
+ return this;
+ }
+
+ public Builder withIPv6AddrGenModeStablePrivacy() {
+ mConfig.mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
+ return this;
+ }
+
public ProvisioningConfiguration build() {
return new ProvisioningConfiguration(mConfig);
}
@@ -331,6 +344,7 @@ public class IpManager extends StateMachine {
/* package */ StaticIpConfiguration mStaticIpConfig;
/* package */ ApfCapabilities mApfCapabilities;
/* package */ int mProvisioningTimeoutMs = DEFAULT_TIMEOUT_MS;
+ /* package */ int mIPv6AddrGenMode = INetd.IPV6_ADDR_GEN_MODE_STABLE_PRIVACY;
public ProvisioningConfiguration() {}
@@ -354,6 +368,7 @@ public class IpManager extends StateMachine {
.add("mStaticIpConfig: " + mStaticIpConfig)
.add("mApfCapabilities: " + mApfCapabilities)
.add("mProvisioningTimeoutMs: " + mProvisioningTimeoutMs)
+ .add("mIPv6AddrGenMode: " + mIPv6AddrGenMode)
.toString();
}
}
@@ -1044,16 +1059,25 @@ public class IpManager extends StateMachine {
return true;
}
+ private void setIPv6AddrGenModeIfSupported() throws RemoteException {
+ try {
+ mNwService.setIPv6AddrGenMode(mInterfaceName, mConfiguration.mIPv6AddrGenMode);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode != OsConstants.EOPNOTSUPP) {
+ throw e;
+ }
+ }
+ }
+
private boolean startIPv6() {
// Set privacy extensions.
try {
mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
+
+ setIPv6AddrGenModeIfSupported();
mNwService.enableIpv6(mInterfaceName);
- } catch (RemoteException re) {
- logError("Unable to change interface settings: %s", re);
- return false;
- } catch (IllegalStateException ie) {
- logError("Unable to change interface settings: %s", ie);
+ } catch (IllegalStateException | RemoteException | ServiceSpecificException e) {
+ logError("Unable to change interface settings: %s", e);
return false;
}
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index ebad81cdda34..5e5ba462cfca 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -816,6 +816,12 @@ public class MockContext extends Context {
/** {@hide} */
@Override
+ public boolean canLoadUnsafeResources() {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@hide} */
+ @Override
public IBinder getActivityToken() {
throw new UnsupportedOperationException();
}
diff --git a/test-runner/tests/Android.mk b/test-runner/tests/Android.mk
index 68fd6621718c..cc9b01d18fa6 100644
--- a/test-runner/tests/Android.mk
+++ b/test-runner/tests/Android.mk
@@ -16,6 +16,13 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# We only want this apk build for tests.
+#
+# Run the tests using the following commands:
+# adb -r install ${ANDROID_PRODUCT_OUT}/data/app/FrameworkTestRunnerTests/FrameworkTestRunnerTests.apk
+# adb shell am instrument \
+ -e notAnnotation android.test.suitebuilder.examples.error.RunAsPartOfSeparateTest \
+ -w com.android.frameworks.testrunner.tests/android.test.InstrumentationTestRunner
+#
LOCAL_MODULE_TAGS := tests
LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/test-runner/tests/src/android/test/TestCaseUtilTest.java b/test-runner/tests/src/android/test/TestCaseUtilTest.java
index bc6fa9200d1b..9d12eafcd34f 100644
--- a/test-runner/tests/src/android/test/TestCaseUtilTest.java
+++ b/test-runner/tests/src/android/test/TestCaseUtilTest.java
@@ -29,9 +29,7 @@ public class TestCaseUtilTest extends TestCase {
List<String> testCaseNames = TestCaseUtil.getTestCaseNames(testSuite, false);
- assertEquals(2, testCaseNames.size());
- assertTrue(testCaseNames.get(0).endsWith("OneTestTestCase"));
- assertTrue(testCaseNames.get(1).endsWith("OneTestTestSuite"));
+ assertEquals(0, testCaseNames.size());
}
public void testGetTestCaseNamesForTestCaseWithSuiteMethod() throws Exception {
diff --git a/test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java b/test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java
index 293c8133eb95..a2e51a197a98 100644
--- a/test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java
+++ b/test-runner/tests/src/android/test/suitebuilder/TestSuiteBuilderTest.java
@@ -135,10 +135,23 @@ public class TestSuiteBuilderTest extends TestCase {
TestSuite testSuite = new OuterTest().buildTestsUnderHereRecursively();
assertContentsInOrder(getTestCaseNames(testSuite),
- "testOuter", "testErrorOne", "testErrorTwo", "testFailOne", "testFailTwo",
- "testInstrumentation", "testLevel1", "testLevel2", "testAnotherOne",
- "testSimpleOne", "testSimpleTwo", "testNonSmoke", "testSmoke", "testSubclass",
- "testSuperclass", "testUnSuppressedMethod");
+ "testOuter",
+ "testPublicConstructor",
+ "testErrorOne",
+ "testErrorTwo",
+ "testFailOne",
+ "testFailTwo",
+ "testInstrumentation",
+ "testLevel1",
+ "testLevel2",
+ "testAnotherOne",
+ "testSimpleOne",
+ "testSimpleTwo",
+ "testNonSmoke",
+ "testSmoke",
+ "testSubclass",
+ "testSuperclass",
+ "testUnSuppressedMethod");
}
private void assertContentsInOrder(List<String> actual, String... source) {
diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java
index f1f6113e86d2..ddf5dd16ece9 100644
--- a/test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java
+++ b/test-runner/tests/src/android/test/suitebuilder/examples/error/ErrorTest.java
@@ -18,6 +18,7 @@ package android.test.suitebuilder.examples.error;
import junit.framework.TestCase;
+@RunAsPartOfSeparateTest
public class ErrorTest extends TestCase {
public void testErrorOne() throws Exception {
diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java
index 428fd23b819d..0170b2f6cc70 100644
--- a/test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java
+++ b/test-runner/tests/src/android/test/suitebuilder/examples/error/FailingTest.java
@@ -18,6 +18,7 @@ package android.test.suitebuilder.examples.error;
import junit.framework.TestCase;
+@RunAsPartOfSeparateTest
public class FailingTest extends TestCase {
public void testFailOne() throws Exception {
diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/error/RunAsPartOfSeparateTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/error/RunAsPartOfSeparateTest.java
new file mode 100644
index 000000000000..2b3a2528a39a
--- /dev/null
+++ b/test-runner/tests/src/android/test/suitebuilder/examples/error/RunAsPartOfSeparateTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+package android.test.suitebuilder.examples.error;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation that marks tests that should only be run as part of a separate test and not on their
+ * own.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface RunAsPartOfSeparateTest {
+}
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index 0d69c892c103..9d71775889d4 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -40,7 +40,7 @@
using ::aapt::configuration::Abi;
using ::aapt::configuration::Artifact;
-using ::aapt::configuration::Configuration;
+using ::aapt::configuration::PostProcessingConfiguration;
using ::android::StringPiece;
using ::android::base::StringPrintf;
@@ -66,8 +66,7 @@ struct OptimizeOptions {
TableFlattenerOptions table_flattener_options;
- // TODO: Come up with a better name for the Configuration struct.
- Maybe<Configuration> configuration;
+ Maybe<PostProcessingConfiguration> configuration;
};
class OptimizeContext : public IAaptContext {
@@ -189,7 +188,7 @@ class OptimizeCommand {
}
if (options_.configuration && options_.output_dir) {
- Configuration& config = options_.configuration.value();
+ PostProcessingConfiguration& config = options_.configuration.value();
// For now, just write out the stripped APK since ABI splitting doesn't modify anything else.
for (const Artifact& artifact : config.artifacts) {
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
index 555cb35c0bb9..0b6743c4c3b6 100644
--- a/tools/aapt2/configuration/ConfigurationParser.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -42,7 +42,7 @@ using ::aapt::configuration::Abi;
using ::aapt::configuration::AndroidManifest;
using ::aapt::configuration::AndroidSdk;
using ::aapt::configuration::Artifact;
-using ::aapt::configuration::Configuration;
+using ::aapt::configuration::PostProcessingConfiguration;
using ::aapt::configuration::GlTexture;
using ::aapt::configuration::Group;
using ::aapt::configuration::Locale;
@@ -125,7 +125,7 @@ ConfigurationParser::ConfigurationParser(std::string contents)
diag_(&noop_) {
}
-Maybe<Configuration> ConfigurationParser::Parse() {
+Maybe<PostProcessingConfiguration> ConfigurationParser::Parse() {
std::istringstream in(contents_);
auto doc = xml::Inflate(&in, diag_, Source("config.xml"));
@@ -157,10 +157,11 @@ Maybe<Configuration> ConfigurationParser::Parse() {
XmlNodeAction& artifacts_action = root_action["artifacts"];
XmlNodeAction& groups_action = root_action["groups"];
- Configuration config;
+ PostProcessingConfiguration config;
// Helper to bind a static method to an action handler in the DOM executor.
- auto bind_handler = [&config](std::function<bool(Configuration*, Element*, IDiagnostics*)> h)
+ auto bind_handler =
+ [&config](std::function<bool(PostProcessingConfiguration*, Element*, IDiagnostics*)> h)
-> XmlNodeAction::ActionFuncWithDiag {
return std::bind(h, &config, std::placeholders::_1, std::placeholders::_2);
};
@@ -189,271 +190,259 @@ Maybe<Configuration> ConfigurationParser::Parse() {
}
ConfigurationParser::ActionHandler ConfigurationParser::artifact_handler_ =
- [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
- Artifact artifact{};
- for (const auto& attr : root_element->attributes) {
- if (attr.name == "name") {
- artifact.name = attr.value;
- } else if (attr.name == "abi-group") {
- artifact.abi_group = {attr.value};
- } else if (attr.name == "screen-density-group") {
- artifact.screen_density_group = {attr.value};
- } else if (attr.name == "locale-group") {
- artifact.locale_group = {attr.value};
- } else if (attr.name == "android-sdk-group") {
- artifact.android_sdk_group = {attr.value};
- } else if (attr.name == "gl-texture-group") {
- artifact.gl_texture_group = {attr.value};
- } else if (attr.name == "device-feature-group") {
- artifact.device_feature_group = {attr.value};
- } else {
- diag->Note(
- DiagMessage() << "Unknown artifact attribute: " << attr.name << " = " << attr.value);
- }
- }
- config->artifacts.push_back(artifact);
- return true;
- };
+ [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+ Artifact artifact{};
+ for (const auto& attr : root_element->attributes) {
+ if (attr.name == "name") {
+ artifact.name = attr.value;
+ } else if (attr.name == "abi-group") {
+ artifact.abi_group = {attr.value};
+ } else if (attr.name == "screen-density-group") {
+ artifact.screen_density_group = {attr.value};
+ } else if (attr.name == "locale-group") {
+ artifact.locale_group = {attr.value};
+ } else if (attr.name == "android-sdk-group") {
+ artifact.android_sdk_group = {attr.value};
+ } else if (attr.name == "gl-texture-group") {
+ artifact.gl_texture_group = {attr.value};
+ } else if (attr.name == "device-feature-group") {
+ artifact.device_feature_group = {attr.value};
+ } else {
+ diag->Note(DiagMessage() << "Unknown artifact attribute: " << attr.name << " = "
+ << attr.value);
+ }
+ }
+ config->artifacts.push_back(artifact);
+ return true;
+};
ConfigurationParser::ActionHandler ConfigurationParser::artifact_format_handler_ =
- [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
- for (auto& node : root_element->children) {
- xml::Text* t;
- if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
- config->artifact_format = TrimWhitespace(t->text).to_string();
- break;
- }
- }
- return true;
- };
+ [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+ for (auto& node : root_element->children) {
+ xml::Text* t;
+ if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+ config->artifact_format = TrimWhitespace(t->text).to_string();
+ break;
+ }
+ }
+ return true;
+};
ConfigurationParser::ActionHandler ConfigurationParser::abi_group_handler_ =
- [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
- std::string label = GetLabel(root_element, diag);
- if (label.empty()) {
- return false;
- }
+ [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+ std::string label = GetLabel(root_element, diag);
+ if (label.empty()) {
+ return false;
+ }
- auto& group = config->abi_groups[label];
- bool valid = true;
+ auto& group = config->abi_groups[label];
+ bool valid = true;
- for (auto* child : root_element->GetChildElements()) {
- if (child->name != "abi") {
- diag->Error(
- DiagMessage() << "Unexpected element in ABI group: " << child->name);
- valid = false;
- } else {
- for (auto& node : child->children) {
- xml::Text* t;
- if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
- group.push_back(kStringToAbiMap.at(TrimWhitespace(t->text).to_string()));
- break;
- }
- }
+ for (auto* child : root_element->GetChildElements()) {
+ if (child->name != "abi") {
+ diag->Error(DiagMessage() << "Unexpected element in ABI group: " << child->name);
+ valid = false;
+ } else {
+ for (auto& node : child->children) {
+ xml::Text* t;
+ if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+ group.push_back(kStringToAbiMap.at(TrimWhitespace(t->text).to_string()));
+ break;
}
}
+ }
+ }
- return valid;
- };
+ return valid;
+};
ConfigurationParser::ActionHandler ConfigurationParser::screen_density_group_handler_ =
- [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
- std::string label = GetLabel(root_element, diag);
- if (label.empty()) {
- return false;
- }
+ [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+ std::string label = GetLabel(root_element, diag);
+ if (label.empty()) {
+ return false;
+ }
- auto& group = config->screen_density_groups[label];
- bool valid = true;
+ auto& group = config->screen_density_groups[label];
+ bool valid = true;
- for (auto* child : root_element->GetChildElements()) {
- if (child->name != "screen-density") {
- diag->Error(
- DiagMessage() << "Unexpected root_element in screen density group: "
- << child->name);
- valid = false;
- } else {
- for (auto& node : child->children) {
- xml::Text* t;
- if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
- ConfigDescription config_descriptor;
- const android::StringPiece& text = TrimWhitespace(t->text);
- if (ConfigDescription::Parse(text, &config_descriptor)) {
- // Copy the density with the minimum SDK version stripped out.
- group.push_back(config_descriptor.CopyWithoutSdkVersion());
- } else {
- diag->Error(
- DiagMessage() << "Could not parse config descriptor for screen-density: "
- << text);
- valid = false;
- }
- break;
- }
+ for (auto* child : root_element->GetChildElements()) {
+ if (child->name != "screen-density") {
+ diag->Error(DiagMessage() << "Unexpected root_element in screen density group: "
+ << child->name);
+ valid = false;
+ } else {
+ for (auto& node : child->children) {
+ xml::Text* t;
+ if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+ ConfigDescription config_descriptor;
+ const android::StringPiece& text = TrimWhitespace(t->text);
+ if (ConfigDescription::Parse(text, &config_descriptor)) {
+ // Copy the density with the minimum SDK version stripped out.
+ group.push_back(config_descriptor.CopyWithoutSdkVersion());
+ } else {
+ diag->Error(DiagMessage()
+ << "Could not parse config descriptor for screen-density: " << text);
+ valid = false;
}
+ break;
}
}
+ }
+ }
- return valid;
- };
+ return valid;
+};
ConfigurationParser::ActionHandler ConfigurationParser::locale_group_handler_ =
- [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
- std::string label = GetLabel(root_element, diag);
- if (label.empty()) {
- return false;
- }
+ [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+ std::string label = GetLabel(root_element, diag);
+ if (label.empty()) {
+ return false;
+ }
- auto& group = config->locale_groups[label];
- bool valid = true;
+ auto& group = config->locale_groups[label];
+ bool valid = true;
- for (auto* child : root_element->GetChildElements()) {
- if (child->name != "locale") {
- diag->Error(
- DiagMessage() << "Unexpected root_element in screen density group: "
- << child->name);
- valid = false;
+ for (auto* child : root_element->GetChildElements()) {
+ if (child->name != "locale") {
+ diag->Error(DiagMessage() << "Unexpected root_element in screen density group: "
+ << child->name);
+ valid = false;
+ } else {
+ Locale entry;
+ for (const auto& attr : child->attributes) {
+ if (attr.name == "lang") {
+ entry.lang = {attr.value};
+ } else if (attr.name == "region") {
+ entry.region = {attr.value};
} else {
- Locale entry;
- for (const auto& attr : child->attributes) {
- if (attr.name == "lang") {
- entry.lang = {attr.value};
- } else if (attr.name == "region") {
- entry.region = {attr.value};
- } else {
- diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name
- << " = " << attr.value);
- }
- }
- group.push_back(entry);
+ diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name << " = " << attr.value);
}
}
+ group.push_back(entry);
+ }
+ }
- return valid;
- };
+ return valid;
+};
ConfigurationParser::ActionHandler ConfigurationParser::android_sdk_group_handler_ =
- [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
- std::string label = GetLabel(root_element, diag);
- if (label.empty()) {
- return false;
- }
-
- auto& group = config->android_sdk_groups[label];
- bool valid = true;
+ [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+ std::string label = GetLabel(root_element, diag);
+ if (label.empty()) {
+ return false;
+ }
- for (auto* child : root_element->GetChildElements()) {
- if (child->name != "android-sdk") {
- diag->Error(
- DiagMessage() << "Unexpected root_element in ABI group: " << child->name);
- valid = false;
+ auto& group = config->android_sdk_groups[label];
+ bool valid = true;
+
+ for (auto* child : root_element->GetChildElements()) {
+ if (child->name != "android-sdk") {
+ diag->Error(DiagMessage() << "Unexpected root_element in ABI group: " << child->name);
+ valid = false;
+ } else {
+ AndroidSdk entry;
+ for (const auto& attr : child->attributes) {
+ if (attr.name == "minSdkVersion") {
+ entry.min_sdk_version = {attr.value};
+ } else if (attr.name == "targetSdkVersion") {
+ entry.target_sdk_version = {attr.value};
+ } else if (attr.name == "maxSdkVersion") {
+ entry.max_sdk_version = {attr.value};
} else {
- AndroidSdk entry;
- for (const auto& attr : child->attributes) {
- if (attr.name == "minSdkVersion") {
- entry.min_sdk_version = {attr.value};
- } else if (attr.name == "targetSdkVersion") {
- entry.target_sdk_version = {attr.value};
- } else if (attr.name == "maxSdkVersion") {
- entry.max_sdk_version = {attr.value};
- } else {
- diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name
- << " = " << attr.value);
- }
- }
+ diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name << " = " << attr.value);
+ }
+ }
- // TODO: Fill in the manifest details when they are finalised.
- for (auto node : child->GetChildElements()) {
- if (node->name == "manifest") {
- if (entry.manifest) {
- diag->Warn(DiagMessage() << "Found multiple manifest tags. Ignoring duplicates.");
- continue;
- }
- entry.manifest = {AndroidManifest()};
- }
+ // TODO: Fill in the manifest details when they are finalised.
+ for (auto node : child->GetChildElements()) {
+ if (node->name == "manifest") {
+ if (entry.manifest) {
+ diag->Warn(DiagMessage() << "Found multiple manifest tags. Ignoring duplicates.");
+ continue;
}
-
- group.push_back(entry);
+ entry.manifest = {AndroidManifest()};
}
}
- return valid;
- };
+ group.push_back(entry);
+ }
+ }
+
+ return valid;
+};
ConfigurationParser::ActionHandler ConfigurationParser::gl_texture_group_handler_ =
- [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
- std::string label = GetLabel(root_element, diag);
- if (label.empty()) {
- return false;
- }
+ [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+ std::string label = GetLabel(root_element, diag);
+ if (label.empty()) {
+ return false;
+ }
- auto& group = config->gl_texture_groups[label];
- bool valid = true;
+ auto& group = config->gl_texture_groups[label];
+ bool valid = true;
- GlTexture result;
- for (auto* child : root_element->GetChildElements()) {
- if (child->name != "gl-texture") {
- diag->Error(
- DiagMessage() << "Unexpected element in GL texture group: "
- << child->name);
- valid = false;
- } else {
- for (const auto& attr : child->attributes) {
- if (attr.name == "name") {
- result.name = attr.value;
- break;
- }
- }
+ GlTexture result;
+ for (auto* child : root_element->GetChildElements()) {
+ if (child->name != "gl-texture") {
+ diag->Error(DiagMessage() << "Unexpected element in GL texture group: " << child->name);
+ valid = false;
+ } else {
+ for (const auto& attr : child->attributes) {
+ if (attr.name == "name") {
+ result.name = attr.value;
+ break;
+ }
+ }
- for (auto* element : child->GetChildElements()) {
- if (element->name != "texture-path") {
- diag->Error(
- DiagMessage() << "Unexpected element in gl-texture element: "
- << child->name);
- valid = false;
- continue;
- }
- for (auto& node : element->children) {
- xml::Text* t;
- if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
- result.texture_paths.push_back(TrimWhitespace(t->text).to_string());
- }
- }
+ for (auto* element : child->GetChildElements()) {
+ if (element->name != "texture-path") {
+ diag->Error(DiagMessage() << "Unexpected element in gl-texture element: " << child->name);
+ valid = false;
+ continue;
+ }
+ for (auto& node : element->children) {
+ xml::Text* t;
+ if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+ result.texture_paths.push_back(TrimWhitespace(t->text).to_string());
}
}
- group.push_back(result);
}
+ }
+ group.push_back(result);
+ }
- return valid;
- };
+ return valid;
+};
ConfigurationParser::ActionHandler ConfigurationParser::device_feature_group_handler_ =
- [](Configuration* config, Element* root_element, IDiagnostics* diag) -> bool {
- std::string label = GetLabel(root_element, diag);
- if (label.empty()) {
- return false;
- }
+ [](PostProcessingConfiguration* config, Element* root_element, IDiagnostics* diag) -> bool {
+ std::string label = GetLabel(root_element, diag);
+ if (label.empty()) {
+ return false;
+ }
- auto& group = config->device_feature_groups[label];
- bool valid = true;
+ auto& group = config->device_feature_groups[label];
+ bool valid = true;
- for (auto* child : root_element->GetChildElements()) {
- if (child->name != "supports-feature") {
- diag->Error(
- DiagMessage() << "Unexpected root_element in device feature group: "
- << child->name);
- valid = false;
- } else {
- for (auto& node : child->children) {
- xml::Text* t;
- if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
- group.push_back(TrimWhitespace(t->text).to_string());
- break;
- }
- }
+ for (auto* child : root_element->GetChildElements()) {
+ if (child->name != "supports-feature") {
+ diag->Error(DiagMessage() << "Unexpected root_element in device feature group: "
+ << child->name);
+ valid = false;
+ } else {
+ for (auto& node : child->children) {
+ xml::Text* t;
+ if ((t = NodeCast<xml::Text>(node.get())) != nullptr) {
+ group.push_back(TrimWhitespace(t->text).to_string());
+ break;
}
}
+ }
+ }
- return valid;
- };
+ return valid;
+};
} // namespace aapt
diff --git a/tools/aapt2/configuration/ConfigurationParser.h b/tools/aapt2/configuration/ConfigurationParser.h
index 0435cbf72a22..3fae5dd0a990 100644
--- a/tools/aapt2/configuration/ConfigurationParser.h
+++ b/tools/aapt2/configuration/ConfigurationParser.h
@@ -117,10 +117,8 @@ struct GlTexture {
}
};
-/**
- * AAPT2 XML configuration binary representation.
- */
-struct Configuration {
+/** AAPT2 XML configuration file binary representation. */
+struct PostProcessingConfiguration {
// TODO: Support named artifacts?
std::vector<Artifact> artifacts;
Maybe<std::string> artifact_format;
@@ -166,7 +164,7 @@ class ConfigurationParser {
* Parses the configuration file and returns the results. If the configuration could not be parsed
* the result is empty and any errors will be displayed with the provided diagnostics context.
*/
- Maybe<configuration::Configuration> Parse();
+ Maybe<configuration::PostProcessingConfiguration> Parse();
protected:
/**
@@ -185,9 +183,8 @@ class ConfigurationParser {
* An ActionHandler for processing XML elements in the XmlActionExecutor. Returns true if the
* element was successfully processed, otherwise returns false.
*/
- using ActionHandler = std::function<bool(configuration::Configuration* config,
- xml::Element* element,
- IDiagnostics* diag)>;
+ using ActionHandler = std::function<bool(configuration::PostProcessingConfiguration* config,
+ xml::Element* element, IDiagnostics* diag)>;
/** Handler for <artifact> tags. */
static ActionHandler artifact_handler_;
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index a8c385823fa9..a4fa1344cb3b 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -32,7 +32,7 @@ namespace {
using android::ResTable_config;
using configuration::Abi;
using configuration::AndroidSdk;
-using configuration::Configuration;
+using configuration::PostProcessingConfiguration;
using configuration::DeviceFeature;
using configuration::GlTexture;
using configuration::Locale;
@@ -139,7 +139,7 @@ TEST_F(ConfigurationParserTest, ValidateFile) {
auto parser = ConfigurationParser::ForContents(kValidConfig).WithDiagnostics(&diag_);
auto result = parser.Parse();
ASSERT_TRUE(result);
- Configuration& value = result.value();
+ PostProcessingConfiguration& value = result.value();
EXPECT_EQ(2ul, value.artifacts.size());
ASSERT_TRUE(value.artifact_format);
EXPECT_EQ(
@@ -190,7 +190,7 @@ TEST_F(ConfigurationParserTest, ArtifactAction) {
auto doc = test::BuildXmlDom(xml);
- Configuration config;
+ PostProcessingConfiguration config;
bool ok = artifact_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
@@ -229,7 +229,7 @@ TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
auto doc = test::BuildXmlDom(xml);
- Configuration config;
+ PostProcessingConfiguration config;
bool ok = artifact_format_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
ASSERT_TRUE(config.artifact_format);
@@ -252,7 +252,7 @@ TEST_F(ConfigurationParserTest, AbiGroupAction) {
auto doc = test::BuildXmlDom(xml);
- Configuration config;
+ PostProcessingConfiguration config;
bool ok = abi_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
@@ -275,7 +275,7 @@ TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
auto doc = test::BuildXmlDom(xml);
- Configuration config;
+ PostProcessingConfiguration config;
bool ok =
screen_density_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
@@ -305,7 +305,7 @@ TEST_F(ConfigurationParserTest, LocaleGroupAction) {
auto doc = test::BuildXmlDom(xml);
- Configuration config;
+ PostProcessingConfiguration config;
bool ok = locale_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
@@ -341,7 +341,7 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
auto doc = test::BuildXmlDom(xml);
- Configuration config;
+ PostProcessingConfiguration config;
bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
@@ -373,7 +373,7 @@ TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
auto doc = test::BuildXmlDom(xml);
- Configuration config;
+ PostProcessingConfiguration config;
bool ok = gl_texture_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);
@@ -402,7 +402,7 @@ TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
auto doc = test::BuildXmlDom(xml);
- Configuration config;
+ PostProcessingConfiguration config;
bool ok
= device_feature_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
ASSERT_TRUE(ok);