Merge "Add device and carrier flags for video calling fallback"
diff --git a/api/test-current.txt b/api/test-current.txt
index 6a70957..201d9b3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -47159,6 +47159,7 @@
method public void setColorMode(int);
method public final void setTitle(java.lang.CharSequence);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000
field public static final int ALPHA_CHANGED = 128; // 0x80
field public static final int ANIMATION_CHANGED = 16; // 0x10
field public static final float BRIGHTNESS_OVERRIDE_FULL = 1.0f;
@@ -47260,6 +47261,7 @@
field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
+ field public java.lang.CharSequence accessibilityTitle;
field public float alpha;
field public float buttonBrightness;
field public float dimAmount;
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 5fedc9e..607e6e0 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -33,17 +33,24 @@
#include <ui/DisplayInfo.h>
#include <ui/PixelFormat.h>
+#include <system/graphics.h>
+
// TODO: Fix Skia.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <SkImageEncoder.h>
#include <SkData.h>
+#include <SkColorSpace.h>
#pragma GCC diagnostic pop
using namespace android;
static uint32_t DEFAULT_DISPLAY_ID = ISurfaceComposer::eDisplayIdMain;
+#define COLORSPACE_UNKNOWN 0
+#define COLORSPACE_SRGB 1
+#define COLORSPACE_DISPLAY_P3 2
+
static void usage(const char* pname)
{
fprintf(stderr,
@@ -67,6 +74,31 @@
}
}
+static sk_sp<SkColorSpace> dataSpaceToColorSpace(android_dataspace d)
+{
+ switch (d) {
+ case HAL_DATASPACE_V0_SRGB:
+ return SkColorSpace::MakeSRGB();
+ case HAL_DATASPACE_DISPLAY_P3:
+ return SkColorSpace::MakeRGB(
+ SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kDCIP3_D65_Gamut);
+ default:
+ return nullptr;
+ }
+}
+
+static uint32_t dataSpaceToInt(android_dataspace d)
+{
+ switch (d) {
+ case HAL_DATASPACE_V0_SRGB:
+ return COLORSPACE_SRGB;
+ case HAL_DATASPACE_DISPLAY_P3:
+ return COLORSPACE_DISPLAY_P3;
+ default:
+ return COLORSPACE_UNKNOWN;
+ }
+}
+
static status_t notifyMediaScanner(const char* fileName) {
String8 cmd("am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file://");
String8 fileUrl("\"");
@@ -139,6 +171,7 @@
void const* base = NULL;
uint32_t w, s, h, f;
+ android_dataspace d;
size_t size = 0;
// Maps orientations from DisplayInfo to ISurfaceComposer
@@ -177,13 +210,15 @@
h = screenshot.getHeight();
s = screenshot.getStride();
f = screenshot.getFormat();
+ d = screenshot.getDataSpace();
size = screenshot.getSize();
}
if (base != NULL) {
if (png) {
const SkImageInfo info =
- SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType);
+ SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType,
+ dataSpaceToColorSpace(d));
SkPixmap pixmap(info, base, s * bytesPerPixel(f));
struct FDWStream final : public SkWStream {
size_t fBytesWritten = 0;
@@ -200,9 +235,11 @@
notifyMediaScanner(fn);
}
} else {
+ uint32_t c = dataSpaceToInt(d);
write(fd, &w, 4);
write(fd, &h, 4);
write(fd, &f, 4);
+ write(fd, &c, 4);
size_t Bpp = bytesPerPixel(f);
for (size_t y=0 ; y<h ; y++) {
write(fd, base, w*Bpp);
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9c2e11d..dec5f4f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -301,6 +301,19 @@
public static final int START_INTENT_NOT_RESOLVED = FIRST_START_FATAL_ERROR_CODE + 9;
/**
+ * Result for IActivityManager.startAssistantActivity: active session is currently hidden.
+ * @hide
+ */
+ public static final int START_ASSISTANT_HIDDEN_SESSION = FIRST_START_FATAL_ERROR_CODE + 10;
+
+ /**
+ * Result for IActivityManager.startAssistantActivity: active session does not match
+ * the requesting token.
+ * @hide
+ */
+ public static final int START_ASSISTANT_NOT_ACTIVE_SESSION = FIRST_START_FATAL_ERROR_CODE + 11;
+
+ /**
* Result for IActivityManaqer.startActivity: the activity was started
* successfully as normal.
* @hide
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index dfa1c57..df55080 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -29,8 +29,8 @@
import android.content.ContentProvider;
import android.content.Context;
import android.content.IContentProvider;
-import android.content.Intent;
import android.content.IIntentReceiver;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
@@ -91,6 +91,7 @@
import android.provider.Downloads;
import android.provider.FontsContract;
import android.provider.Settings;
+import android.renderscript.RenderScriptCacheDir;
import android.security.NetworkSecurityPolicy;
import android.security.net.config.NetworkSecurityConfigProvider;
import android.util.AndroidRuntimeException;
@@ -114,7 +115,6 @@
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
-import android.renderscript.RenderScriptCacheDir;
import android.webkit.WebView;
import com.android.internal.annotations.GuardedBy;
@@ -128,8 +128,21 @@
import com.android.internal.util.FastPrintWriter;
import com.android.org.conscrypt.OpenSSLSocketImpl;
import com.android.org.conscrypt.TrustedCertificateStore;
+
+import dalvik.system.BaseDexClassLoader;
+import dalvik.system.CloseGuard;
+import dalvik.system.VMDebug;
+import dalvik.system.VMRuntime;
+
import com.google.android.collect.Lists;
+import libcore.io.DropBox;
+import libcore.io.EventLogger;
+import libcore.io.IoUtils;
+import libcore.net.event.NetworkEventDispatcher;
+
+import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
@@ -146,16 +159,6 @@
import java.util.Objects;
import java.util.TimeZone;
-import libcore.io.DropBox;
-import libcore.io.EventLogger;
-import libcore.io.IoUtils;
-import libcore.net.event.NetworkEventDispatcher;
-import dalvik.system.BaseDexClassLoader;
-import dalvik.system.CloseGuard;
-import dalvik.system.VMDebug;
-import dalvik.system.VMRuntime;
-import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
-
final class RemoteServiceException extends AndroidRuntimeException {
public RemoteServiceException(String msg) {
super(msg);
@@ -2887,6 +2890,9 @@
TAG, "Handling launch of " + r);
// Initialize before creating the activity
+ if (!ThreadedRenderer.sRendererDisabled) {
+ GraphicsEnvironment.earlyInitEGL();
+ }
WindowManagerGlobal.initialize();
Activity a = performLaunchActivity(r, customIntent);
@@ -5372,26 +5378,45 @@
WindowManagerGlobal.getInstance().trimMemory(level);
}
- private void setupGraphicsSupport(Context context, File cacheDir) {
- if (Process.isIsolated()) {
- // Isolated processes aren't going to do UI.
- return;
- }
+ private void setupGraphicsSupport(Context context) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setupGraphicsSupport");
- try {
- int uid = Process.myUid();
- String[] packages = getPackageManager().getPackagesForUid(uid);
- if (packages != null) {
- ThreadedRenderer.setupDiskCache(cacheDir);
- RenderScriptCacheDir.setupDiskCache(cacheDir);
- GraphicsEnvironment.setupGraphicsEnvironment(context);
+ // The system package doesn't have real data directories, so don't set up cache paths.
+ if (!"android".equals(context.getPackageName())) {
+ // This cache location probably points at credential-encrypted
+ // storage which may not be accessible yet; assign it anyway instead
+ // of pointing at device-encrypted storage.
+ final File cacheDir = context.getCacheDir();
+ if (cacheDir != null) {
+ // Provide a usable directory for temporary files
+ System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
+ } else {
+ Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
+ + "due to missing cache directory");
}
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
+ // Setup a location to store generated/compiled graphics code.
+ final Context deviceContext = context.createDeviceProtectedStorageContext();
+ final File codeCacheDir = deviceContext.getCodeCacheDir();
+ if (codeCacheDir != null) {
+ try {
+ int uid = Process.myUid();
+ String[] packages = getPackageManager().getPackagesForUid(uid);
+ if (packages != null) {
+ ThreadedRenderer.setupDiskCache(cacheDir);
+ RenderScriptCacheDir.setupDiskCache(cacheDir);
+ }
+ } catch (RemoteException e) {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ throw e.rethrowFromSystemServer();
+ }
+ } else {
+ Log.w(TAG, "Unable to use shader/script cache: missing code-cache directory");
+ }
}
+
+ GraphicsEnvironment.chooseDriver(context);
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
private void updateDefaultDensity() {
@@ -5664,27 +5689,8 @@
updateLocaleListFromAppContext(appContext,
mResourcesManager.getConfiguration().getLocales());
- if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
- // This cache location probably points at credential-encrypted
- // storage which may not be accessible yet; assign it anyway instead
- // of pointing at device-encrypted storage.
- final File cacheDir = appContext.getCacheDir();
- if (cacheDir != null) {
- // Provide a usable directory for temporary files
- System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
- } else {
- Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "
- + "due to missing cache directory");
- }
-
- // Setup a location to store generated/compiled graphics code.
- final Context deviceContext = appContext.createDeviceProtectedStorageContext();
- final File codeCacheDir = deviceContext.getCodeCacheDir();
- if (codeCacheDir != null) {
- setupGraphicsSupport(appContext, codeCacheDir);
- } else {
- Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
- }
+ if (!Process.isIsolated()) {
+ setupGraphicsSupport(appContext);
}
// If we use profiles, setup the dex reporter to notify package manager
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 84efcee..467fc95 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1953,6 +1953,12 @@
case ActivityManager.START_VOICE_HIDDEN_SESSION:
throw new IllegalStateException(
"Cannot start voice activity on a hidden session");
+ case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
+ throw new IllegalStateException(
+ "Session calling startAssistantActivity does not match active session");
+ case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
+ throw new IllegalStateException(
+ "Cannot start assistant activity on a hidden session");
case ActivityManager.START_CANCELED:
throw new AndroidRuntimeException("Activity could not be started for "
+ intent);
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index f9eaba9..07c6055 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -35,23 +35,12 @@
private static final String TAG = "GraphicsEnvironment";
private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
- public static void setupGraphicsEnvironment(Context context) {
- chooseDriver(context);
-
- // Now that we've figured out which driver to use for this process, load and initialize it.
- // This can take multiple frame periods, and it would otherwise happen as part of the first
- // frame, increasing first-frame latency. Starting it here, as a low-priority background
- // thread, means that it's usually done long before we start drawing the first frame,
- // without significantly disrupting other activity launch work.
- Thread eglInitThread = new Thread(
- () -> {
- EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
- },
- "EGL Init");
- eglInitThread.start();
- }
-
- private static void chooseDriver(Context context) {
+ /**
+ * Choose whether the current process should use the builtin or an updated driver.
+ *
+ * @hide
+ */
+ public static void chooseDriver(Context context) {
String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
if (driverPackageName == null || driverPackageName.isEmpty()) {
return;
@@ -101,6 +90,27 @@
setDriverPath(paths);
}
+ /**
+ * Start a background thread to initialize EGL.
+ *
+ * Initializing EGL involves loading and initializing the graphics driver. Some drivers take
+ * several 10s of milliseconds to do this, so doing it on-demand when an app tries to render
+ * its first frame adds directly to user-visible app launch latency. By starting it earlier
+ * on a separate thread, it can usually be finished well before the UI is ready to be drawn.
+ *
+ * Should only be called after chooseDriver().
+ *
+ * @hide
+ */
+ public static void earlyInitEGL() {
+ Thread eglInitThread = new Thread(
+ () -> {
+ EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+ },
+ "EGL Init");
+ eglInitThread.start();
+ }
+
private static String chooseAbi(ApplicationInfo ai) {
String isa = VMRuntime.getCurrentInstructionSet();
if (ai.primaryCpuAbi != null &&
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 31b2dcc..d1ebc6e 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -318,6 +318,17 @@
}
/**
+ * The ID passed to setGroup(), or the override, or null.
+ * @hide
+ */
+ public String getGroup() {
+ if (overrideGroupKey != null) {
+ return overrideGroupKey;
+ }
+ return getNotification().getGroup();
+ }
+
+ /**
* Sets the override group key.
*/
public void setOverrideGroupKey(String overrideGroupKey) {
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index a2a129d..625dd9e 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -235,6 +235,8 @@
@Override
public void hide() {
+ // Remove any pending messages to show the session
+ mHandlerCaller.removeMessages(MSG_SHOW);
mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_HIDE));
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index da81efc..aacd687 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -358,7 +358,6 @@
private long mNativeProxy;
private boolean mInitialized = false;
private RenderNode mRootNode;
- private Choreographer mChoreographer;
private boolean mRootNodeNeedsUpdate;
private boolean mEnabled;
@@ -425,8 +424,6 @@
/**
* Indicates whether threaded rendering is currently requested but not
* necessarily enabled yet.
- *
- * @return True to request threaded rendering, false otherwise.
*/
void setRequested(boolean requested) {
mRequested = requested;
@@ -597,6 +594,13 @@
}
/**
+ * Enable/disable wide gamut rendering on this renderer.
+ */
+ void setWideGamut(boolean wideGamut) {
+ nSetWideGamut(mNativeProxy, wideGamut);
+ }
+
+ /**
* Gets the current width of the surface. This is the width that the surface
* was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
*
@@ -933,11 +937,11 @@
if (mInitialized) return;
mInitialized = true;
mAppContext = context.getApplicationContext();
- initSched(context, renderProxy);
+ initSched(renderProxy);
initGraphicsStats();
}
- private void initSched(Context context, long renderProxy) {
+ private void initSched(long renderProxy) {
try {
int tid = nGetRenderThreadTid(renderProxy);
ActivityManager.getService().setRenderThread(tid);
@@ -1007,6 +1011,7 @@
private static native void nSetLightCenter(long nativeProxy,
float lightX, float lightY, float lightZ);
private static native void nSetOpaque(long nativeProxy, boolean opaque);
+ private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
private static native void nDestroy(long nativeProxy, long rootRenderNode);
private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 84baeb7..8105d24 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10026,12 +10026,20 @@
// Going from one cluster to another, so save last-focused.
// This covers cluster jumps because they are always FOCUS_DOWN
oldFocus.setFocusedInCluster(oldCluster);
+ if (!(oldFocus.mParent instanceof ViewGroup)) {
+ return;
+ }
if (direction == FOCUS_FORWARD || direction == FOCUS_BACKWARD) {
// This is a result of ordered navigation so consider navigation through
// the previous cluster "complete" and clear its last-focused memory.
- if (oldFocus.mParent instanceof ViewGroup) {
- ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus);
- }
+ ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus);
+ } else if (oldFocus instanceof ViewGroup
+ && ((ViewGroup) oldFocus).getDescendantFocusability()
+ == ViewGroup.FOCUS_AFTER_DESCENDANTS
+ && ViewRootImpl.isViewDescendantOf(this, oldFocus)) {
+ // This means oldFocus is not focusable since it obviously has a focusable
+ // child (this). Don't restore focus to it in the future.
+ ((ViewGroup) oldFocus.mParent).clearFocusedInCluster(oldFocus);
}
}
}
@@ -13088,7 +13096,7 @@
// about in case nothing has focus. even if this specific view
// isn't focusable, it may contain something that is, so let
// the root view try to give this focus if nothing else does.
- if ((mParent != null) && (mBottom > mTop) && (mRight > mLeft)) {
+ if ((mParent != null)) {
mParent.focusableViewAvailable(this);
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c5d4ed2..10de583 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -833,8 +833,9 @@
public void focusableViewAvailable(View v) {
if (mParent != null
// shortcut: don't report a new focusable view if we block our descendants from
- // getting focus
+ // getting focus or if we're not visible
&& (getDescendantFocusability() != FOCUS_BLOCK_DESCENDANTS)
+ && ((mViewFlags & VISIBILITY_MASK) == VISIBLE)
&& (isFocusableInTouchMode() || !shouldBlockFocusForTouchscreen())
// shortcut: don't report a new focusable view if we already are focused
// (and we don't prefer our descendants)
@@ -1159,18 +1160,25 @@
// Determine whether we have a focused descendant.
final int descendantFocusability = getDescendantFocusability();
if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
- final int count = mChildrenCount;
- final View[] children = mChildren;
+ return hasFocusableChild(dispatchExplicit);
+ }
- for (int i = 0; i < count; i++) {
- final View child = children[i];
+ return false;
+ }
- // In case the subclass has overridden has[Explicit]Focusable, dispatch
- // to the expected one for each child even though we share logic here.
- if ((dispatchExplicit && child.hasExplicitFocusable())
- || (!dispatchExplicit && child.hasFocusable())) {
- return true;
- }
+ boolean hasFocusableChild(boolean dispatchExplicit) {
+ // Determine whether we have a focusable descendant.
+ final int count = mChildrenCount;
+ final View[] children = mChildren;
+
+ for (int i = 0; i < count; i++) {
+ final View child = children[i];
+
+ // In case the subclass has overridden has[Explicit]Focusable, dispatch
+ // to the expected one for each child even though we share logic here.
+ if ((dispatchExplicit && child.hasExplicitFocusable())
+ || (!dispatchExplicit && child.hasFocusable())) {
+ return true;
}
}
@@ -3230,7 +3238,7 @@
// will refer to a view not-in a cluster.
return restoreFocusInCluster(View.FOCUS_DOWN);
}
- if (isKeyboardNavigationCluster()) {
+ if (isKeyboardNavigationCluster() || (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
return false;
}
int descendentFocusability = getDescendantFocusability();
@@ -3248,7 +3256,7 @@
return true;
}
}
- if (descendentFocusability == FOCUS_AFTER_DESCENDANTS) {
+ if (descendentFocusability == FOCUS_AFTER_DESCENDANTS && !hasFocusableChild(false)) {
return super.requestFocus(FOCUS_DOWN, null);
}
return false;
@@ -4915,7 +4923,8 @@
child.mParent = this;
}
- if (child.hasFocus()) {
+ final boolean childHasFocus = child.hasFocus();
+ if (childHasFocus) {
requestChildFocus(child, child.findFocus());
}
@@ -4928,6 +4937,9 @@
needGlobalAttributesUpdate(true);
}
ai.mKeepScreenOn = lastKeepOn;
+ if (!childHasFocus && child.hasFocusable()) {
+ focusableViewAvailable(child);
+ }
}
if (child.isLayoutDirectionInherited()) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 3759f9e..9a3d1b9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -35,6 +35,7 @@
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -960,8 +961,12 @@
final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0
|| insets.top != 0 || insets.bottom != 0;
final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
+ final boolean wideGamut =
+ attrs.getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
+
mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
attrs.getTitle().toString());
+ mAttachInfo.mThreadedRenderer.setWideGamut(wideGamut);
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mHardwareAccelerated =
mAttachInfo.mHardwareAccelerationRequested = true;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 3f91476..12ff217 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1903,6 +1903,7 @@
*
* @hide
*/
+ @TestApi
public CharSequence accessibilityTitle;
/**
@@ -2089,6 +2090,7 @@
out.writeInt(needsMenuKey);
out.writeInt(accessibilityIdOfAnchor);
TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
+ out.writeInt(mColorMode);
out.writeLong(hideTimeoutMilliseconds);
}
@@ -2143,6 +2145,7 @@
needsMenuKey = in.readInt();
accessibilityIdOfAnchor = in.readInt();
accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ mColorMode = in.readInt();
hideTimeoutMilliseconds = in.readLong();
}
@@ -2185,8 +2188,11 @@
/** {@hide} */
public static final int ACCESSIBILITY_ANCHOR_CHANGED = 1 << 24;
/** {@hide} */
+ @TestApi
public static final int ACCESSIBILITY_TITLE_CHANGED = 1 << 25;
/** {@hide} */
+ public static final int COLOR_MODE_CHANGED = 1 << 26;
+ /** {@hide} */
public static final int EVERYTHING_CHANGED = 0xffffffff;
// internal buffer to backup/restore parameters under compatibility mode.
@@ -2364,6 +2370,11 @@
changes |= ACCESSIBILITY_TITLE_CHANGED;
}
+ if (mColorMode != o.mColorMode) {
+ mColorMode = o.mColorMode;
+ changes |= COLOR_MODE_CHANGED;
+ }
+
// This can't change, it's only set at window creation time.
hideTimeoutMilliseconds = o.hideTimeoutMilliseconds;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index cc14542..ec2b302 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1956,12 +1956,12 @@
* messages to a certain target origin. See
* <a href="https://html.spec.whatwg.org/multipage/comms.html#posting-messages">
* HTML5 spec</a> for how target origin can be used.
+ * <p>
+ * A target origin can be set as a wildcard ("*"). However this is not recommended.
+ * See the page above for security issues.
*
* @param message the WebMessage
- * @param targetOrigin the target origin. This is the origin of the page
- * that is intended to receive the message. For best security
- * practices, the user should not specify a wildcard (*) when
- * specifying the origin.
+ * @param targetOrigin the target origin.
*/
public void postWebMessage(WebMessage message, Uri targetOrigin) {
checkThread();
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 82071d7..fcb44af 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1718,20 +1718,17 @@
break;
case KeyEvent.KEYCODE_TAB:
- // XXX Sometimes it is useful to be able to TAB through the items in
+ // TODO: Sometimes it is useful to be able to TAB through the items in
// a GridView sequentially. Unfortunately this can create an
// asymmetry in TAB navigation order unless the list selection
// always reverts to the top or bottom when receiving TAB focus from
- // another widget. Leaving this behavior disabled for now but
- // perhaps it should be configurable (and more comprehensive).
- if (false) {
- if (event.hasNoModifiers()) {
- handled = resurrectSelectionIfNeeded()
- || sequenceScroll(FOCUS_FORWARD);
- } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
- handled = resurrectSelectionIfNeeded()
- || sequenceScroll(FOCUS_BACKWARD);
- }
+ // another widget.
+ if (event.hasNoModifiers()) {
+ handled = resurrectSelectionIfNeeded()
+ || sequenceScroll(FOCUS_FORWARD);
+ } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
+ handled = resurrectSelectionIfNeeded()
+ || sequenceScroll(FOCUS_BACKWARD);
}
break;
}
@@ -1991,7 +1988,7 @@
if (!mStackFromBottom) {
rowStart = childIndex - (childIndex % mNumColumns);
- rowEnd = Math.max(rowStart + mNumColumns - 1, count);
+ rowEnd = Math.min(rowStart + mNumColumns - 1, count);
} else {
rowEnd = count - 1 - (invertedIndex - (invertedIndex % mNumColumns));
rowStart = Math.max(0, rowEnd - mNumColumns + 1);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index de56092..6b328ea 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1587,7 +1587,7 @@
if (textColorHighlight != 0) {
setHighlightColor(textColorHighlight);
}
- setRawTextSize(textSize);
+ setRawTextSize(textSize, true /* shouldRequestLayout */);
setElegantTextHeight(elegant);
setLetterSpacing(letterSpacing);
setFontFeatureSettings(fontFeatureSettings);
@@ -1757,7 +1757,10 @@
autoSizeMinTextSizeInPx,
autoSizeMaxTextSizeInPx,
DEFAULT_AUTO_SIZE_GRANULARITY_IN_PX);
- setupAutoSizeText();
+ if (setupAutoSizeText()) {
+ autoSizeText();
+ invalidate();
+ }
break;
default:
throw new IllegalArgumentException(
@@ -1807,7 +1810,11 @@
validateAndSetAutoSizeTextTypeUniformConfiguration(autoSizeMinTextSizeInPx,
autoSizeMaxTextSizeInPx,
autoSizeStepGranularityInPx);
- setupAutoSizeText();
+
+ if (setupAutoSizeText()) {
+ autoSizeText();
+ invalidate();
+ }
}
}
@@ -1856,7 +1863,11 @@
} else {
mHasPresetAutoSizeValues = false;
}
- setupAutoSizeText();
+
+ if (setupAutoSizeText()) {
+ autoSizeText();
+ invalidate();
+ }
}
}
@@ -2014,20 +2025,19 @@
: uniqueValidSizes.toArray();
}
- private void setupAutoSizeText() {
+ private boolean setupAutoSizeText() {
if (supportsAutoSizeText() && mAutoSizeTextType == AUTO_SIZE_TEXT_TYPE_UNIFORM) {
// Calculate the sizes set based on minimum size, maximum size and step size if we do
// not have a predefined set of sizes or if the current sizes array is empty.
if (!mHasPresetAutoSizeValues || mAutoSizeTextSizesInPx.length == 0) {
- // Calculate sizes to choose from based on the current auto-size configuration.
- int autoSizeValuesLength = (int) Math.ceil(
- (mAutoSizeMaxTextSizeInPx - mAutoSizeMinTextSizeInPx)
- / mAutoSizeStepGranularityInPx);
- // Also reserve a slot for the max size if it fits.
- if ((mAutoSizeMaxTextSizeInPx - mAutoSizeMinTextSizeInPx)
- % mAutoSizeStepGranularityInPx == 0) {
+ int autoSizeValuesLength = 1;
+ float currentSize = Math.round(mAutoSizeMinTextSizeInPx);
+ while (Math.round(currentSize + mAutoSizeStepGranularityInPx)
+ <= Math.round(mAutoSizeMaxTextSizeInPx)) {
autoSizeValuesLength++;
+ currentSize += mAutoSizeStepGranularityInPx;
}
+
int[] autoSizeTextSizesInPx = new int[autoSizeValuesLength];
float sizeToAdd = mAutoSizeMinTextSizeInPx;
for (int i = 0; i < autoSizeValuesLength; i++) {
@@ -2038,8 +2048,11 @@
}
mNeedsAutoSizeText = true;
- autoSizeText();
+ } else {
+ mNeedsAutoSizeText = false;
}
+
+ return mNeedsAutoSizeText;
}
private int[] parseDimensionArray(TypedArray dimens) {
@@ -3387,7 +3400,7 @@
final int textSize = ta.getDimensionPixelSize(R.styleable.TextAppearance_textSize, 0);
if (textSize != 0) {
- setRawTextSize(textSize);
+ setRawTextSize(textSize, true /* shouldRequestLayout */);
}
final ColorStateList textColorHint = ta.getColorStateList(
@@ -3612,11 +3625,11 @@
*/
public void setTextSize(int unit, float size) {
if (!isAutoSizeEnabled()) {
- setTextSizeInternal(unit, size);
+ setTextSizeInternal(unit, size, true /* shouldRequestLayout */);
}
}
- private void setTextSizeInternal(int unit, float size) {
+ private void setTextSizeInternal(int unit, float size, boolean shouldRequestLayout) {
Context c = getContext();
Resources r;
@@ -3626,15 +3639,15 @@
r = c.getResources();
}
- setRawTextSize(TypedValue.applyDimension(
- unit, size, r.getDisplayMetrics()));
+ setRawTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics()),
+ shouldRequestLayout);
}
- private void setRawTextSize(float size) {
+ private void setRawTextSize(float size, boolean shouldRequestLayout) {
if (size != mTextPaint.getTextSize()) {
mTextPaint.setTextSize(size);
- if (mLayout != null) {
+ if (shouldRequestLayout && mLayout != null) {
// Do not auto-size right after setting the text size.
mNeedsAutoSizeText = false;
nullLayouts();
@@ -8257,23 +8270,44 @@
* Automatically computes and sets the text size.
*/
private void autoSizeText() {
- if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0) return;
- final int maxWidth = getWidth() - getTotalPaddingLeft() - getTotalPaddingRight();
- final int maxHeight = getHeight() - getExtendedPaddingBottom() - getExtendedPaddingTop();
-
- if (maxWidth <= 0 || maxHeight <= 0) {
+ if (!isAutoSizeEnabled()) {
return;
}
- synchronized (TEMP_RECTF) {
- TEMP_RECTF.setEmpty();
- TEMP_RECTF.right = maxWidth;
- TEMP_RECTF.bottom = maxHeight;
- final float optimalTextSize = findLargestTextSizeWhichFits(TEMP_RECTF);
- if (optimalTextSize != getTextSize()) {
- setTextSizeInternal(TypedValue.COMPLEX_UNIT_PX, optimalTextSize);
+ if (mNeedsAutoSizeText) {
+ if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0) {
+ return;
+ }
+
+ final int availableWidth = mHorizontallyScrolling
+ ? VERY_WIDE
+ : getMeasuredWidth() - getTotalPaddingLeft() - getTotalPaddingRight();
+ final int availableHeight = getMeasuredHeight() - getExtendedPaddingBottom()
+ - getExtendedPaddingTop();
+
+ if (availableWidth <= 0 || availableHeight <= 0) {
+ return;
+ }
+
+ synchronized (TEMP_RECTF) {
+ TEMP_RECTF.setEmpty();
+ TEMP_RECTF.right = availableWidth;
+ TEMP_RECTF.bottom = availableHeight;
+ final float optimalTextSize = findLargestTextSizeWhichFits(TEMP_RECTF);
+
+ if (optimalTextSize != getTextSize()) {
+ setTextSizeInternal(TypedValue.COMPLEX_UNIT_PX, optimalTextSize,
+ false /* shouldRequestLayout */);
+
+ makeNewLayout(availableWidth, 0 /* hintWidth */, UNKNOWN_BORING, UNKNOWN_BORING,
+ mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(),
+ false /* bringIntoView */);
+ }
}
}
+ // Always try to auto-size if enabled. Functions that do not want to trigger auto-sizing
+ // after the next layout pass should set this to false.
+ mNeedsAutoSizeText = true;
}
/**
@@ -8315,11 +8349,8 @@
mTempTextPaint.set(getPaint());
mTempTextPaint.setTextSize(suggestedSizeInPx);
- final int availableWidth = mHorizontallyScrolling
- ? VERY_WIDE
- : getMeasuredWidth() - getTotalPaddingLeft() - getTotalPaddingRight();
final StaticLayout.Builder layoutBuilder = StaticLayout.Builder.obtain(
- text, 0, text.length(), mTempTextPaint, availableWidth);
+ text, 0, text.length(), mTempTextPaint, Math.round(availableSpace.right));
layoutBuilder.setAlignment(getLayoutAlignment())
.setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier())
@@ -8469,6 +8500,7 @@
// In a fixed-height view, so use our new text layout.
if (mLayoutParams.height != LayoutParams.WRAP_CONTENT
&& mLayoutParams.height != LayoutParams.MATCH_PARENT) {
+ autoSizeText();
invalidate();
return;
}
@@ -8477,6 +8509,7 @@
// so use our new text layout.
if (mLayout.getHeight() == oldht
&& (mHintLayout == null || mHintLayout.getHeight() == oldht)) {
+ autoSizeText();
invalidate();
return;
}
@@ -8503,16 +8536,8 @@
mDeferScroll = -1;
bringPointIntoView(Math.min(curs, mText.length()));
}
-
- if (isAutoSizeEnabled()) {
- if (mNeedsAutoSizeText) {
- // Call auto-size after the width and height have been calculated.
- autoSizeText();
- }
- // Always try to auto-size if enabled. Functions that do not want to trigger auto-sizing
- // after the next layout round should set this to false.
- mNeedsAutoSizeText = true;
- }
+ // Call auto-size after the width and height have been calculated.
+ autoSizeText();
}
private boolean isShowingHint() {
diff --git a/core/java/com/android/internal/app/NightDisplayController.java b/core/java/com/android/internal/app/NightDisplayController.java
index d19f1ec..bb54085 100644
--- a/core/java/com/android/internal/app/NightDisplayController.java
+++ b/core/java/com/android/internal/app/NightDisplayController.java
@@ -109,17 +109,39 @@
}
/**
- * Sets whether Night display should be activated.
+ * Sets whether Night display should be activated. This also sets the last activated time.
*
* @param activated {@code true} if Night display should be activated
* @return {@code true} if the activated value was set successfully
*/
public boolean setActivated(boolean activated) {
+ if (isActivated() != activated) {
+ Secure.putLongForUser(mContext.getContentResolver(),
+ Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, System.currentTimeMillis(),
+ mUserId);
+ }
return Secure.putIntForUser(mContext.getContentResolver(),
Secure.NIGHT_DISPLAY_ACTIVATED, activated ? 1 : 0, mUserId);
}
/**
+ * Returns the time when Night display's activation state last changed, or {@code null} if it
+ * has never been changed.
+ */
+ public Calendar getLastActivatedTime() {
+ final ContentResolver cr = mContext.getContentResolver();
+ final long lastActivatedTimeMillis = Secure.getLongForUser(
+ cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1, mUserId);
+ if (lastActivatedTimeMillis < 0) {
+ return null;
+ }
+
+ final Calendar lastActivatedTime = Calendar.getInstance();
+ lastActivatedTime.setTimeInMillis(lastActivatedTimeMillis);
+ return lastActivatedTime;
+ }
+
+ /**
* Returns the current auto mode value controlling when Night display will be automatically
* activated. One of {@link #AUTO_MODE_DISABLED}, {@link #AUTO_MODE_CUSTOM}, or
* {@link #AUTO_MODE_TWILIGHT}.
diff --git a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
index 568c883..9fbc4a8 100644
--- a/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
+++ b/core/java/com/android/internal/os/KernelUidCpuFreqTimeReader.java
@@ -53,10 +53,21 @@
private SparseArray<long[]> mLastUidCpuFreqTimeMs = new SparseArray<>();
+ // We check the existence of proc file a few times (just in case it is not ready yet when we
+ // start reading) and if it is not available, we simply ignore further read requests.
+ private static final int TOTAL_READ_ERROR_COUNT = 5;
+ private int mReadErrorCounter;
+ private boolean mProcFileAvailable;
+
public void readDelta(@Nullable Callback callback) {
+ if (!mProcFileAvailable && mReadErrorCounter >= TOTAL_READ_ERROR_COUNT) {
+ return;
+ }
try (BufferedReader reader = new BufferedReader(new FileReader(UID_TIMES_PROC_FILE))) {
readDelta(reader, callback);
+ mProcFileAvailable = true;
} catch (IOException e) {
+ mReadErrorCounter++;
Slog.e(TAG, "Failed to read " + UID_TIMES_PROC_FILE + ": " + e);
}
}
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index a019ea1..3f35c91 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -93,4 +93,10 @@
* @param fadeoutDuration the duration of the exit animation, in milliseconds
*/
void startKeyguardExitAnimation(long startTime, long fadeoutDuration);
+
+ /**
+ * Notifies the Keyguard that the power key was pressed while locked and launched Home rather
+ * than putting the device to sleep or waking up.
+ */
+ void onShortPowerPressedGoHome();
}
diff --git a/core/java/com/android/internal/view/TooltipPopup.java b/core/java/com/android/internal/view/TooltipPopup.java
index ebbbdbb..d834e63 100644
--- a/core/java/com/android/internal/view/TooltipPopup.java
+++ b/core/java/com/android/internal/view/TooltipPopup.java
@@ -25,6 +25,7 @@
import android.view.View;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import android.widget.PopupWindow;
import android.widget.TextView;
public class TooltipPopup {
@@ -32,6 +33,7 @@
private final Context mContext;
+ private final PopupWindow mPopupWindow;
private final View mContentView;
private final TextView mMessageView;
@@ -43,6 +45,8 @@
public TooltipPopup(Context context) {
mContext = context;
+ mPopupWindow = new PopupWindow(context);
+ mPopupWindow.setBackgroundDrawable(null);
mContentView = LayoutInflater.from(mContext).inflate(
com.android.internal.R.layout.tooltip, null);
mMessageView = (TextView) mContentView.findViewById(
@@ -70,17 +74,16 @@
computePosition(anchorView, anchorX, anchorY, fromTouch, mLayoutParams);
- WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
- wm.addView(mContentView, mLayoutParams);
+ mPopupWindow.setContentView(mContentView);
+ mPopupWindow.showAtLocation(
+ anchorView, mLayoutParams.gravity, mLayoutParams.x, mLayoutParams.y);
}
public void hide() {
if (!isShowing()) {
return;
}
-
- WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
- wm.removeView(mContentView);
+ mPopupWindow.dismiss();
}
public View getContentView() {
@@ -88,7 +91,7 @@
}
public boolean isShowing() {
- return mContentView.getParent() != null;
+ return mPopupWindow.isShowing();
}
public void updateContent(CharSequence tooltipText) {
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index d476ea0..e3b9178 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1714,6 +1714,10 @@
setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1L, UserHandle.USER_SYSTEM);
}
+ public void disableSyntheticPassword() {
+ setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0L, UserHandle.USER_SYSTEM);
+ }
+
public boolean isSyntheticPasswordEnabled() {
return getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM) != 0;
}
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 5f803da..f04abec 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -63,14 +63,17 @@
static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jobject jbitmap,
jint tileModeX, jint tileModeY) {
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- SkBitmap bitmap;
+ sk_sp<SkImage> image;
if (jbitmap) {
// Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
// we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
- android::bitmap::toBitmap(env, jbitmap).getSkBitmapForShaders(&bitmap);
+ image = android::bitmap::toBitmap(env, jbitmap).makeImage();
}
- sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+ if (!image.get()) {
+ SkBitmap bitmap;
+ image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+ }
sk_sp<SkShader> baseShader = image->makeShader(
(SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY);
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 497f00c..97aa562 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -221,11 +221,20 @@
return NULL;
}
}
+
+ sk_sp<SkColorSpace> colorSpace;
+ if (screenshot->getDataSpace() == HAL_DATASPACE_DISPLAY_P3) {
+ colorSpace = SkColorSpace::MakeRGB(
+ SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kDCIP3_D65_Gamut);
+ } else {
+ colorSpace = SkColorSpace::MakeSRGB();
+ }
+
SkImageInfo screenshotInfo = SkImageInfo::Make(screenshot->getWidth(),
screenshot->getHeight(),
colorType,
alphaType,
- GraphicsJNI::defaultColorSpace());
+ colorSpace);
const size_t rowBytes =
screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 4c530d7..2657140 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -208,8 +208,15 @@
void detachAnimators() {
// Remove animators from the list and post a delayed message in future to end the animator
+ // For infinite animators, remove the listener so we no longer hold a global ref to the AVD
+ // java object, and therefore the AVD objects in both native and Java can be properly
+ // released.
for (auto& anim : mRunningVDAnimators) {
detachVectorDrawableAnimator(anim.get());
+ anim->clearOneShotListener();
+ }
+ for (auto& anim : mPausedVDAnimators) {
+ anim->clearOneShotListener();
}
mRunningVDAnimators.clear();
mPausedVDAnimators.clear();
@@ -674,6 +681,12 @@
proxy->setOpaque(opaque);
}
+static void android_view_ThreadedRenderer_setWideGamut(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jboolean wideGamut) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ proxy->setWideGamut(wideGamut);
+}
+
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
@@ -865,7 +878,8 @@
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> rawConsumer;
BufferQueue::createBufferQueue(&producer, &rawConsumer);
- rawConsumer->setMaxBufferCount(1);
+ // We only need 1 buffer but some drivers have bugs so workaround it by setting max count to 2
+ rawConsumer->setMaxBufferCount(2);
sp<BufferItemConsumer> consumer = new BufferItemConsumer(rawConsumer,
GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_NEVER);
consumer->setDefaultBufferSize(width, height);
@@ -974,6 +988,7 @@
{ "nSetup", "(JFII)V", (void*) android_view_ThreadedRenderer_setup },
{ "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
{ "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
+ { "nSetWideGamut", "(JZ)V", (void*) android_view_ThreadedRenderer_setWideGamut },
{ "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
{ "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
{ "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 76310b8..9c4d489 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3228,6 +3228,9 @@
<!-- Alert windows notification strings -->
<skip />
+ <!-- Name of notification channel group the system post notification to inform the use about apps
+ that are drawing ui on-top of other apps (alert-windows) [CHAR LIMIT=NONE] -->
+ <string name="alert_windows_notification_channel_group_name">Display over other apps</string>
<!-- Name of notification channel the system post notification to inform the use about apps
that are drawing ui on-top of other apps (alert-windows) [CHAR LIMIT=NONE] -->
<string name="alert_windows_notification_channel_name"><xliff:g id="name" example="Google Maps">%s</xliff:g> displaying over other apps</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ca3baa6..6554d44 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2965,6 +2965,7 @@
<java-symbol type="drawable" name="resolver_icon_placeholder" />
<!-- Alert windows notification -->
+ <java-symbol type="string" name="alert_windows_notification_channel_group_name" />
<java-symbol type="string" name="alert_windows_notification_channel_name" />
<java-symbol type="string" name="alert_windows_notification_title" />
<java-symbol type="string" name="alert_windows_notification_message" />
diff --git a/core/tests/coretests/src/android/widget/touchmode/TouchModeFocusableTest.java b/core/tests/coretests/src/android/widget/touchmode/TouchModeFocusableTest.java
index dd07a08..3ddeef0 100644
--- a/core/tests/coretests/src/android/widget/touchmode/TouchModeFocusableTest.java
+++ b/core/tests/coretests/src/android/widget/touchmode/TouchModeFocusableTest.java
@@ -16,16 +16,15 @@
package android.widget.touchmode;
-import android.widget.layout.linear.LLEditTextThenButton;
-import static android.util.TouchModeFlexibleAsserts.assertInTouchModeAfterTap;
import static android.util.TouchModeFlexibleAsserts.assertInTouchModeAfterClick;
+import static android.util.TouchModeFlexibleAsserts.assertInTouchModeAfterTap;
import android.test.ActivityInstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
-import android.view.KeyEvent;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.layout.linear.LLEditTextThenButton;
/**
* Some views, like edit texts, can keep and gain focus even when in touch mode.
@@ -64,7 +63,8 @@
@LargeTest
public void testClickEditTextGivesItFocus() {
// go down to button
- sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getActivity().runOnUiThread(() -> mButton.requestFocus());
+ getInstrumentation().waitForIdleSync();
assertTrue("button should have focus", mButton.isFocused());
assertInTouchModeAfterClick(this, mEditText);
@@ -77,11 +77,12 @@
// isn't focusable in touch mode.
@LargeTest
public void testEnterTouchModeGivesFocusBackToFocusableInTouchMode() {
- sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getActivity().runOnUiThread(() -> mButton.requestFocus());
+ getInstrumentation().waitForIdleSync();
assertTrue("button should have focus",
mButton.isFocused());
-
+
assertInTouchModeAfterClick(this, mButton);
assertTrue("should be in touch mode", mButton.isInTouchMode());
assertNull("nothing should have focus", getActivity().getCurrentFocus());
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 8ce7ed0..aa38f31 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -44,6 +44,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -493,7 +494,7 @@
case TYPE_DATA:
return getDataLength() == otherIcon.getDataLength()
&& getDataOffset() == otherIcon.getDataOffset()
- && getDataBytes() == otherIcon.getDataBytes();
+ && Arrays.equals(getDataBytes(), otherIcon.getDataBytes());
case TYPE_RESOURCE:
return getResId() == otherIcon.getResId()
&& Objects.equals(getResPackage(), otherIcon.getResPackage());
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index d0f0949..8cc0aa7 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -58,7 +58,9 @@
"uniform mat4 textureTransform;\n"
"uniform mediump vec2 textureDimension;\n";
const char* gVS_Header_Uniforms_HasRoundRectClip =
- "uniform mat4 roundRectInvTransform;\n";
+ "uniform mat4 roundRectInvTransform;\n"
+ "uniform mediump vec4 roundRectInnerRectLTWH;\n"
+ "uniform mediump float roundRectRadius;\n";
const char* gVS_Header_Varyings_HasTexture =
"varying vec2 outTexCoords;\n";
const char* gVS_Header_Varyings_HasColors =
@@ -81,7 +83,7 @@
"varying highp vec2 sweep;\n",
};
const char* gVS_Header_Varyings_HasRoundRectClip =
- "varying highp vec2 roundRectPos;\n";
+ "varying mediump vec2 roundRectPos;\n";
const char* gVS_Main =
"\nvoid main(void) {\n";
const char* gVS_Main_OutTexCoords =
@@ -113,7 +115,7 @@
" alpha = vtxAlpha;\n";
const char* gVS_Main_HasRoundRectClip =
- " roundRectPos = (roundRectInvTransform * transformedPosition).xy;\n";
+ " roundRectPos = ((roundRectInvTransform * transformedPosition).xy / roundRectRadius) - roundRectInnerRectLTWH.xy;\n";
const char* gVS_Footer =
"}\n\n";
@@ -158,8 +160,8 @@
};
const char* gFS_Uniforms_HasRoundRectClip =
- "uniform vec4 roundRectInnerRectLTRB;\n"
- "uniform float roundRectRadius;\n";
+ "uniform mediump vec4 roundRectInnerRectLTWH;\n"
+ "uniform mediump float roundRectRadius;\n";
const char* gFS_Uniforms_ColorSpaceConversion =
// TODO: Should we use a 3D LUT to combine the matrix and transfer functions?
@@ -431,15 +433,18 @@
" fragColor = blendColors(colorBlend, fragColor);\n"
};
-// Note: LTRB -> xyzw
+// Note: LTWH (left top width height) -> xyzw
+// roundRectPos is now divided by roundRectRadius in vertex shader
+// after we also subtract roundRectInnerRectLTWH.xy from roundRectPos
const char* gFS_Main_FragColor_HasRoundRectClip =
- " mediump vec2 fragToLT = roundRectInnerRectLTRB.xy - roundRectPos;\n"
- " mediump vec2 fragFromRB = roundRectPos - roundRectInnerRectLTRB.zw;\n"
+ " mediump vec2 fragToLT = -roundRectPos;\n"
+ " mediump vec2 fragFromRB = roundRectPos - roundRectInnerRectLTWH.zw;\n"
- // divide + multiply by 128 to avoid falling out of range in length() function
- " mediump vec2 dist = max(max(fragToLT, fragFromRB), vec2(0.0, 0.0)) / 128.0;\n"
- " mediump float linearDist = roundRectRadius - (length(dist) * 128.0);\n"
- " gl_FragColor *= clamp(linearDist, 0.0, 1.0);\n";
+ // since distance is divided by radius, it's in [0;1] so precision is not an issue
+ // this also lets us clamp(0.0, 1.0) instead of max() which is cheaper on GPUs
+ " mediump vec2 dist = clamp(max(fragToLT, fragFromRB), 0.0, 1.0);\n"
+ " mediump float linearDist = clamp(roundRectRadius - (length(dist) * roundRectRadius), 0.0, 1.0);\n"
+ " gl_FragColor *= linearDist;\n";
const char* gFS_Main_DebugHighlight =
" gl_FragColor.rgb = vec3(0.0, gl_FragColor.a, 0.0);\n";
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 4e6a7db..6dde005 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -26,16 +26,12 @@
#include <log/log.h>
#include <cutils/ashmem.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
#include <private/gui/ComposerService.h>
#include <binder/IServiceManager.h>
#include <ui/PixelFormat.h>
#include <SkCanvas.h>
+#include <SkImagePriv.h>
namespace android {
@@ -89,171 +85,6 @@
return sk_sp<Bitmap>(new Bitmap(addr, size, info, rowBytes, std::move(ctable)));
}
-#define FENCE_TIMEOUT 2000000000
-
-// TODO: handle SRGB sanely
-static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
- switch (internalFormat) {
- case GL_LUMINANCE:
- return PIXEL_FORMAT_RGBA_8888;
- case GL_SRGB8_ALPHA8:
- return PIXEL_FORMAT_RGBA_8888;
- case GL_RGBA:
- return PIXEL_FORMAT_RGBA_8888;
- case GL_RGB:
- return PIXEL_FORMAT_RGB_565;
- case GL_RGBA16F:
- return PIXEL_FORMAT_RGBA_FP16;
- default:
- LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
- return PIXEL_FORMAT_UNKNOWN;
- }
-}
-
-class AutoEglFence {
-public:
- AutoEglFence(EGLDisplay display)
- : mDisplay(display) {
- fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
- }
-
- ~AutoEglFence() {
- if (fence != EGL_NO_SYNC_KHR) {
- eglDestroySyncKHR(mDisplay, fence);
- }
- }
-
- EGLSyncKHR fence = EGL_NO_SYNC_KHR;
-private:
- EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
-class AutoEglImage {
-public:
- AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
- : mDisplay(display) {
- EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
- image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
- EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
- }
-
- ~AutoEglImage() {
- if (image != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mDisplay, image);
- }
- }
-
- EGLImageKHR image = EGL_NO_IMAGE_KHR;
-private:
- EGLDisplay mDisplay = EGL_NO_DISPLAY;
-};
-
-class AutoGlTexture {
-public:
- AutoGlTexture(uirenderer::Caches& caches)
- : mCaches(caches) {
- glGenTextures(1, &mTexture);
- caches.textureState().bindTexture(mTexture);
- }
-
- ~AutoGlTexture() {
- mCaches.textureState().deleteTexture(mTexture);
- }
-
-private:
- uirenderer::Caches& mCaches;
- GLuint mTexture = 0;
-};
-
-static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
- GraphicBuffer& buffer, GLint format, GLint type) {
- EGLDisplay display = eglGetCurrentDisplay();
- LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
- "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
- uirenderer::renderthread::EglManager::eglErrorString());
- // We use an EGLImage to access the content of the GraphicBuffer
- // The EGL image is later bound to a 2D texture
- EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
- AutoEglImage autoImage(display, clientBuffer);
- if (autoImage.image == EGL_NO_IMAGE_KHR) {
- ALOGW("Could not create EGL image, err =%s",
- uirenderer::renderthread::EglManager::eglErrorString());
- return false;
- }
- AutoGlTexture glTexture(caches);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
-
- GL_CHECKPOINT(MODERATE);
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
- format, type, bitmap.getPixels());
-
- GL_CHECKPOINT(MODERATE);
-
- // The fence is used to wait for the texture upload to finish
- // properly. We cannot rely on glFlush() and glFinish() as
- // some drivers completely ignore these API calls
- AutoEglFence autoFence(display);
- if (autoFence.fence == EGL_NO_SYNC_KHR) {
- LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
- return false;
- }
- // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
- // pipeline flush (similar to what a glFlush() would do.)
- EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
- EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
- if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
- LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
- return false;
- }
- return true;
-}
-
-sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(uirenderer::renderthread::RenderThread& renderThread,
- SkBitmap& skBitmap) {
- renderThread.eglManager().initialize();
- uirenderer::Caches& caches = uirenderer::Caches::getInstance();
-
- const SkImageInfo& info = skBitmap.info();
- if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
- ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
- return nullptr;
- }
-
- bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
- bool hasLinearBlending = caches.extensions().hasLinearBlending();
- GLint format, type, internalFormat;
- uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
- needSRGB && hasLinearBlending, &internalFormat, &format, &type);
-
- PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
- sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
- GraphicBuffer::USAGE_HW_TEXTURE |
- GraphicBuffer::USAGE_SW_WRITE_NEVER |
- GraphicBuffer::USAGE_SW_READ_NEVER,
- std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
-
- status_t error = buffer->initCheck();
- if (error < 0) {
- ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
- return nullptr;
- }
-
- SkBitmap bitmap;
- if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
- hasLinearBlending))) {
- sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
- bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
- } else {
- bitmap = skBitmap;
- }
-
- if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
- return nullptr;
- }
- return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
-}
-
sk_sp<Bitmap> Bitmap::allocateHardwareBitmap(SkBitmap& bitmap) {
return uirenderer::renderthread::RenderProxy::allocateHardwareBitmap(bitmap);
}
@@ -392,6 +223,12 @@
, mPixelStorageType(PixelStorageType::Hardware) {
mPixelStorage.hardware.buffer = buffer;
buffer->incStrong(buffer);
+ setImmutable(); // HW bitmaps are always immutable
+ if (uirenderer::Properties::isSkiaEnabled()) {
+ // TODO: add color correctness for Skia pipeline - pass null color space for now
+ mImage = SkImage::MakeFromAHardwareBuffer(reinterpret_cast<AHardwareBuffer*>(buffer),
+ mInfo.alphaType(), nullptr);
+ }
}
Bitmap::~Bitmap() {
@@ -486,16 +323,6 @@
outBitmap->setPixelRef(sk_ref_sp(this), 0, 0);
}
-void Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) {
- if (isHardware() && uirenderer::Properties::isSkiaEnabled()) {
- getSkBitmap(outBitmap);
- } else {
- outBitmap->setInfo(info(), rowBytes());
- outBitmap->setPixelRef(sk_ref_sp(this), 0, 0);
- outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
- }
-}
-
void Bitmap::getBounds(SkRect* bounds) const {
SkASSERT(bounds);
bounds->set(0, 0, SkIntToScalar(width()), SkIntToScalar(height()));
@@ -508,4 +335,20 @@
return nullptr;
}
+sk_sp<SkImage> Bitmap::makeImage() {
+ sk_sp<SkImage> image = mImage;
+ if (!image) {
+ SkASSERT(!(isHardware() && uirenderer::Properties::isSkiaEnabled()));
+ SkBitmap skiaBitmap;
+ skiaBitmap.setInfo(info(), rowBytes());
+ skiaBitmap.setPixelRef(sk_ref_sp(this), 0, 0);
+ skiaBitmap.setHasHardwareMipMap(mHasHardwareMipMap);
+ // Note we don't cache in this case, because the raster image holds a pointer to this Bitmap
+ // internally and ~Bitmap won't be invoked.
+ // TODO: refactor Bitmap to not derive from SkPixelRef, which would allow caching here.
+ image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
+ }
+ return image;
+}
+
} // namespace android
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 9a76715..364240670 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -18,10 +18,12 @@
#include <SkBitmap.h>
#include <SkColorSpace.h>
#include <SkColorTable.h>
+#include <SkImage.h>
#include <SkImageInfo.h>
#include <SkPixelRef.h>
#include <cutils/compiler.h>
#include <ui/GraphicBuffer.h>
+#include <SkImage.h>
namespace android {
@@ -57,15 +59,13 @@
static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
- static sk_sp<Bitmap> allocateHardwareBitmap(uirenderer::renderthread::RenderThread&,
- SkBitmap& bitmap);
-
Bitmap(void* address, size_t allocSize, const SkImageInfo& info, size_t rowBytes,
sk_sp<SkColorTable> ctable);
Bitmap(void* address, void* context, FreeFunc freeFunc,
const SkImageInfo& info, size_t rowBytes, sk_sp<SkColorTable> ctable);
Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info,
size_t rowBytes, sk_sp<SkColorTable> ctable);
+ Bitmap(GraphicBuffer* buffer, const SkImageInfo& info);
int rowBytesAsPixels() const {
return rowBytes() >> SkColorTypeShiftPerPixel(mInfo.colorType());
@@ -78,10 +78,6 @@
void getSkBitmap(SkBitmap* outBitmap);
- // Ugly hack: in case of hardware bitmaps, it sets nullptr as pixels pointer
- // so it would crash if anyone tries to render this bitmap.
- void getSkBitmapForShaders(SkBitmap* outBitmap);
-
int getAshmemFd() const;
size_t getAllocationByteCount() const;
@@ -105,8 +101,11 @@
}
GraphicBuffer* graphicBuffer();
+
+ // makeImage creates or returns a cached SkImage. Can be invoked from UI or render thread.
+ // Caching is supported only for HW Bitmaps with skia pipeline.
+ sk_sp<SkImage> makeImage();
private:
- Bitmap(GraphicBuffer* buffer, const SkImageInfo& info);
virtual ~Bitmap();
void* getStorage() const;
@@ -135,6 +134,8 @@
GraphicBuffer* buffer;
} hardware;
} mPixelStorage;
+
+ sk_sp<SkImage> mImage; // Cache is used only for HW Bitmaps with Skia pipeline.
};
} //namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index ae13131..095d32e 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -16,6 +16,7 @@
#include "SkiaOpenGLPipeline.h"
+#include "hwui/Bitmap.h"
#include "DeferredLayerUpdater.h"
#include "GlLayer.h"
#include "LayerDrawable.h"
@@ -155,7 +156,8 @@
}
}
-bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
+ ColorMode colorMode) {
if (mEglSurface != EGL_NO_SURFACE) {
mEglManager.destroySurface(mEglSurface);
@@ -163,7 +165,8 @@
}
if (surface) {
- mEglSurface = mEglManager.createSurface(surface);
+ const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
+ mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
}
if (mEglSurface != EGL_NO_SURFACE) {
@@ -197,6 +200,186 @@
}
}
+#define FENCE_TIMEOUT 2000000000
+
+class AutoEglFence {
+public:
+ AutoEglFence(EGLDisplay display)
+ : mDisplay(display) {
+ fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+ }
+
+ ~AutoEglFence() {
+ if (fence != EGL_NO_SYNC_KHR) {
+ eglDestroySyncKHR(mDisplay, fence);
+ }
+ }
+
+ EGLSyncKHR fence = EGL_NO_SYNC_KHR;
+private:
+ EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoEglImage {
+public:
+ AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
+ : mDisplay(display) {
+ EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+ image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+ EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
+ }
+
+ ~AutoEglImage() {
+ if (image != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(mDisplay, image);
+ }
+ }
+
+ EGLImageKHR image = EGL_NO_IMAGE_KHR;
+private:
+ EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoSkiaGlTexture {
+public:
+ AutoSkiaGlTexture() {
+ glGenTextures(1, &mTexture);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ }
+
+ ~AutoSkiaGlTexture() {
+ glDeleteTextures(1, &mTexture);
+ }
+
+private:
+ GLuint mTexture = 0;
+};
+
+sk_sp<Bitmap> SkiaOpenGLPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
+ SkBitmap& skBitmap) {
+ renderThread.eglManager().initialize();
+
+ sk_sp<GrContext> grContext = sk_ref_sp(renderThread.getGrContext());
+ const SkImageInfo& info = skBitmap.info();
+ PixelFormat pixelFormat;
+ GLint format, type;
+ bool isSupported = false;
+
+ //TODO: add support for linear blending (when ANDROID_ENABLE_LINEAR_BLENDING is defined)
+ switch (info.colorType()) {
+ case kRGBA_8888_SkColorType:
+ isSupported = true;
+ // ARGB_4444 and Index_8 are both upconverted to RGBA_8888
+ case kIndex_8_SkColorType:
+ case kARGB_4444_SkColorType:
+ pixelFormat = PIXEL_FORMAT_RGBA_8888;
+ format = GL_RGBA;
+ type = GL_UNSIGNED_BYTE;
+ break;
+ case kRGBA_F16_SkColorType:
+ isSupported = grContext->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig);
+ if (isSupported) {
+ type = GL_HALF_FLOAT;
+ pixelFormat = PIXEL_FORMAT_RGBA_FP16;
+ } else {
+ type = GL_UNSIGNED_BYTE;
+ pixelFormat = PIXEL_FORMAT_RGBA_8888;
+ }
+ format = GL_RGBA;
+ break;
+ case kRGB_565_SkColorType:
+ isSupported = true;
+ pixelFormat = PIXEL_FORMAT_RGB_565;
+ format = GL_RGB;
+ type = GL_UNSIGNED_SHORT_5_6_5;
+ break;
+ case kGray_8_SkColorType:
+ isSupported = true;
+ pixelFormat = PIXEL_FORMAT_RGBA_8888;
+ format = GL_LUMINANCE;
+ type = GL_UNSIGNED_BYTE;
+ break;
+ default:
+ ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
+ return nullptr;
+ }
+
+ SkBitmap bitmap;
+ if (isSupported) {
+ bitmap = skBitmap;
+ } else {
+ bitmap.allocPixels(SkImageInfo::MakeN32(info.width(), info.height(), info.alphaType(),
+ nullptr));
+ bitmap.eraseColor(0);
+ if (info.colorType() == kRGBA_F16_SkColorType) {
+ // Drawing RGBA_F16 onto ARGB_8888 is not supported
+ skBitmap.readPixels(bitmap.info().makeColorSpace(SkColorSpace::MakeSRGB()),
+ bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
+ } else {
+ SkCanvas canvas(bitmap);
+ canvas.drawBitmap(skBitmap, 0.0f, 0.0f, nullptr);
+ }
+ }
+
+ sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
+ GraphicBuffer::USAGE_HW_TEXTURE |
+ GraphicBuffer::USAGE_SW_WRITE_NEVER |
+ GraphicBuffer::USAGE_SW_READ_NEVER,
+ std::string("Bitmap::allocateSkiaHardwareBitmap pid [") + std::to_string(getpid()) + "]");
+
+ status_t error = buffer->initCheck();
+ if (error < 0) {
+ ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+ return nullptr;
+ }
+
+ //upload the bitmap into a texture
+ EGLDisplay display = eglGetCurrentDisplay();
+ LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
+ "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
+ uirenderer::renderthread::EglManager::eglErrorString());
+ // We use an EGLImage to access the content of the GraphicBuffer
+ // The EGL image is later bound to a 2D texture
+ EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer->getNativeBuffer();
+ AutoEglImage autoImage(display, clientBuffer);
+ if (autoImage.image == EGL_NO_IMAGE_KHR) {
+ ALOGW("Could not create EGL image, err =%s",
+ uirenderer::renderthread::EglManager::eglErrorString());
+ return nullptr;
+ }
+ AutoSkiaGlTexture glTexture;
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
+ GL_CHECKPOINT(MODERATE);
+
+ // glTexSubImage2D is synchronous in sense that it memcpy() from pointer that we provide.
+ // But asynchronous in sense that driver may upload texture onto hardware buffer when we first
+ // use it in drawing
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, info.width(), info.height(), format, type,
+ bitmap.getPixels());
+ GL_CHECKPOINT(MODERATE);
+
+ // The fence is used to wait for the texture upload to finish
+ // properly. We cannot rely on glFlush() and glFinish() as
+ // some drivers completely ignore these API calls
+ AutoEglFence autoFence(display);
+ if (autoFence.fence == EGL_NO_SYNC_KHR) {
+ LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
+ return nullptr;
+ }
+ // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
+ // pipeline flush (similar to what a glFlush() would do.)
+ EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
+ EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
+ if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
+ LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
+ return nullptr;
+ }
+
+ grContext->resetContext(kTextureBinding_GrGLBackendState);
+
+ return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
+}
+
} /* namespace skiapipeline */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index 36685dd..d5471de 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -19,6 +19,9 @@
#include "SkiaPipeline.h"
namespace android {
+
+class Bitmap;
+
namespace uirenderer {
namespace skiapipeline {
@@ -40,12 +43,15 @@
FrameInfo* currentFrameInfo, bool* requireSwap) override;
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
DeferredLayerUpdater* createTextureLayer() override;
- bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior) override;
+ bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior,
+ renderthread::ColorMode colorMode) override;
void onStop() override;
bool isSurfaceReady() override;
bool isContextReady() override;
static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+ static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
+ SkBitmap& skBitmap);
private:
renderthread::EglManager& mEglManager;
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
index 04aeb7c..89697d7 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLReadback.cpp
@@ -86,23 +86,17 @@
textureMatrix.mapRect(&skiaSrcRect);
if (skiaSrcRect.intersect(bufferRect)) {
- SkPoint srcOrigin = SkPoint::Make(skiaSrcRect.fLeft, skiaSrcRect.fTop);
+ // we render in an offscreen buffer to scale and to avoid an issue b/62262733
+ // with reading incorrect data from EGLImage backed SkImage (likely a driver bug)
+ sk_sp<SkSurface> scaledSurface = SkSurface::MakeRenderTarget(
+ grContext.get(), SkBudgeted::kYes, bitmap->info());
+ SkPaint paint;
+ paint.setBlendMode(SkBlendMode::kSrc);
+ scaledSurface->getCanvas()->drawImageRect(image, skiaSrcRect,
+ SkRect::MakeWH(bitmap->width(), bitmap->height()), &paint);
+ image = scaledSurface->makeImageSnapshot();
- // if we need to scale the result we must render to an offscreen buffer
- if (bitmap->width() != skiaSrcRect.width()
- || bitmap->height() != skiaSrcRect.height()) {
- sk_sp<SkSurface> scaledSurface = SkSurface::MakeRenderTarget(
- grContext.get(), SkBudgeted::kYes, bitmap->info());
- SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc);
- scaledSurface->getCanvas()->drawImageRect(image, skiaSrcRect,
- SkRect::MakeWH(bitmap->width(), bitmap->height()), &paint);
- image = scaledSurface->makeImageSnapshot();
- srcOrigin.set(0,0);
- }
-
- if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(),
- srcOrigin.fX, srcOrigin.fY)) {
+ if (image->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), 0, 0)) {
copyResult = CopyResult::Success;
}
}
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 75f1adc..88293db 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -159,11 +159,11 @@
GrContext* context = thread.getGrContext();
if (context) {
ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
- SkBitmap skiaBitmap;
- bitmap->getSkBitmap(&skiaBitmap);
- sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
- SkImage_pinAsTexture(image.get(), context);
- SkImage_unpinAsTexture(image.get(), context);
+ auto image = bitmap->makeImage();
+ if (image.get() && !bitmap->isHardware()) {
+ SkImage_pinAsTexture(image.get(), context);
+ SkImage_unpinAsTexture(image.get(), context);
+ }
}
}
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index cf8b4dd..a0cce98 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -156,30 +156,25 @@
}
void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) {
- SkBitmap skBitmap;
- bitmap.getSkBitmap(&skBitmap);
-
- sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
+ sk_sp<SkImage> image = bitmap.makeImage();
SkPaint tmpPaint;
mRecorder.drawImage(image, left, top, nonAAPaint(paint, &tmpPaint));
// if image->unique() is true, then mRecorder.drawImage failed for some reason. It also means
// it is not safe to store a raw SkImage pointer, because the image object will be destroyed
// when this function ends.
- if (!skBitmap.isImmutable() && image.get() && !image->unique()) {
+ if (!bitmap.isImmutable() && image.get() && !image->unique()) {
mDisplayList->mMutableImages.push_back(image.get());
}
}
void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, const SkMatrix& matrix,
const SkPaint* paint) {
- SkBitmap bitmap;
- hwuiBitmap.getSkBitmap(&bitmap);
SkAutoCanvasRestore acr(&mRecorder, true);
concat(matrix);
- sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+ sk_sp<SkImage> image = hwuiBitmap.makeImage();
SkPaint tmpPaint;
mRecorder.drawImage(image, 0, 0, nonAAPaint(paint, &tmpPaint));
- if (!bitmap.isImmutable() && image.get() && !image->unique()) {
+ if (!hwuiBitmap.isImmutable() && image.get() && !image->unique()) {
mDisplayList->mMutableImages.push_back(image.get());
}
}
@@ -187,14 +182,12 @@
void SkiaRecordingCanvas::drawBitmap(Bitmap& hwuiBitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
float dstBottom, const SkPaint* paint) {
- SkBitmap bitmap;
- hwuiBitmap.getSkBitmap(&bitmap);
SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom);
SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
- sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+ sk_sp<SkImage> image = hwuiBitmap.makeImage();
SkPaint tmpPaint;
mRecorder.drawImageRect(image, srcRect, dstRect, nonAAPaint(paint, &tmpPaint));
- if (!bitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty()
+ if (!hwuiBitmap.isImmutable() && image.get() && !image->unique() && !srcRect.isEmpty()
&& !dstRect.isEmpty()) {
mDisplayList->mMutableImages.push_back(image.get());
}
@@ -202,11 +195,8 @@
void SkiaRecordingCanvas::drawNinePatch(Bitmap& hwuiBitmap, const Res_png_9patch& chunk,
float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint) {
- SkBitmap bitmap;
- hwuiBitmap.getSkBitmap(&bitmap);
-
SkCanvas::Lattice lattice;
- NinePatchUtils::SetLatticeDivs(&lattice, chunk, bitmap.width(), bitmap.height());
+ NinePatchUtils::SetLatticeDivs(&lattice, chunk, hwuiBitmap.width(), hwuiBitmap.height());
lattice.fFlags = nullptr;
int numFlags = 0;
@@ -223,11 +213,11 @@
lattice.fBounds = nullptr;
SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
- sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+ sk_sp<SkImage> image = hwuiBitmap.makeImage();
SkPaint tmpPaint;
mRecorder.drawImageLattice(image.get(), lattice, dst, nonAAPaint(paint, &tmpPaint));
- if (!bitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
+ if (!hwuiBitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
mDisplayList->mMutableImages.push_back(image.get());
}
}
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index d28e605..f1ef9e6 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -131,13 +131,15 @@
void SkiaVulkanPipeline::onStop() {
}
-bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
+ ColorMode colorMode) {
if (mVkSurface) {
mVkManager.destroySurface(mVkSurface);
mVkSurface = nullptr;
}
if (surface) {
+ // TODO: handle color mode
mVkSurface = mVkManager.createSurface(surface);
}
@@ -158,6 +160,25 @@
(*functor)(mode, nullptr);
}
+sk_sp<Bitmap> SkiaVulkanPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
+ SkBitmap& skBitmap) {
+ //TODO: implement this function for Vulkan pipeline
+ //code below is a hack to avoid crashing because of missing HW Bitmap support
+ sp<GraphicBuffer> buffer = new GraphicBuffer(skBitmap.info().width(), skBitmap.info().height(),
+ PIXEL_FORMAT_RGBA_8888,
+ GraphicBuffer::USAGE_HW_TEXTURE |
+ GraphicBuffer::USAGE_SW_WRITE_NEVER |
+ GraphicBuffer::USAGE_SW_READ_NEVER,
+ std::string("SkiaVulkanPipeline::allocateHardwareBitmap pid [")
+ + std::to_string(getpid()) + "]");
+ status_t error = buffer->initCheck();
+ if (error < 0) {
+ ALOGW("SkiaVulkanPipeline::allocateHardwareBitmap() failed in GraphicBuffer.create()");
+ return nullptr;
+ }
+ return sk_sp<Bitmap>(new Bitmap(buffer.get(), skBitmap.info()));
+}
+
} /* namespace skiapipeline */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index aab1d7a..3481312 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -41,12 +41,15 @@
FrameInfo* currentFrameInfo, bool* requireSwap) override;
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
DeferredLayerUpdater* createTextureLayer() override;
- bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior) override;
+ bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior,
+ renderthread::ColorMode colorMode) override;
void onStop() override;
bool isSurfaceReady() override;
bool isContextReady() override;
static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor);
+ static sk_sp<Bitmap> allocateHardwareBitmap(renderthread::RenderThread& thread,
+ SkBitmap& skBitmap);
private:
renderthread::VulkanManager& mVkManager;
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 481932d..2c92924 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -296,14 +296,20 @@
// TODO: avoid query, and cache values (or RRCS ptr) in program
const RoundRectClipState* state = glop.roundRectClipState;
const Rect& innerRect = state->innerRect;
- glUniform4f(fill.program->getUniform("roundRectInnerRectLTRB"),
- innerRect.left, innerRect.top,
- innerRect.right, innerRect.bottom);
- glUniformMatrix4fv(fill.program->getUniform("roundRectInvTransform"),
- 1, GL_FALSE, &state->matrix.data[0]);
// add half pixel to round out integer rect space to cover pixel centers
float roundedOutRadius = state->radius + 0.5f;
+
+ // Divide by the radius to simplify the calculations in the fragment shader
+ // roundRectPos is also passed from vertex shader relative to top/left & radius
+ glUniform4f(fill.program->getUniform("roundRectInnerRectLTWH"),
+ innerRect.left / roundedOutRadius, innerRect.top / roundedOutRadius,
+ (innerRect.right - innerRect.left) / roundedOutRadius,
+ (innerRect.bottom - innerRect.top) / roundedOutRadius);
+
+ glUniformMatrix4fv(fill.program->getUniform("roundRectInvTransform"),
+ 1, GL_FALSE, &state->matrix.data[0]);
+
glUniform1f(fill.program->getUniform("roundRectRadius"),
roundedOutRadius);
}
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index cbc5163..e2a4a2a 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -186,7 +186,8 @@
mNativeSurface = surface;
- bool hasSurface = mRenderPipeline->setSurface(surface, mSwapBehavior);
+ ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::Srgb;
+ bool hasSurface = mRenderPipeline->setSurface(surface, mSwapBehavior, colorMode);
mFrameNumber = -1;
@@ -241,6 +242,10 @@
mOpaque = opaque;
}
+void CanvasContext::setWideGamut(bool wideGamut) {
+ mWideColorGamut = wideGamut;
+}
+
bool CanvasContext::makeCurrent() {
if (mStopped) return false;
@@ -437,8 +442,8 @@
if (mNativeSurface.get()) {
int durationUs;
nsecs_t dequeueStart = mNativeSurface->getLastDequeueStartTime();
- if (dequeueStart < mCurrentFrameInfo->get(FrameInfoIndex::Vsync)) {
- // Ignoring dequeue duration as it happened prior to vsync
+ if (dequeueStart < mCurrentFrameInfo->get(FrameInfoIndex::SyncStart)) {
+ // Ignoring dequeue duration as it happened prior to frame render start
// and thus is not part of the frame.
swap.dequeueDuration = 0;
} else {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 33eda96..76623f9 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -128,6 +128,7 @@
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
void setLightCenter(const Vector3& lightCenter);
void setOpaque(bool opaque);
+ void setWideGamut(bool wideGamut);
bool makeCurrent();
void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
int64_t syncQueued, RenderNode* target);
@@ -240,6 +241,7 @@
nsecs_t mLastDropVsync = 0;
bool mOpaque;
+ bool mWideColorGamut = false;
BakedOpRenderer::LightInfo mLightInfo;
FrameBuilder::LightGeometry mLightGeometry = { {0, 0, 0}, 0 };
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 44af5fd..53d42a2 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -76,12 +76,16 @@
static struct {
bool bufferAge = false;
bool setDamage = false;
+ bool noConfigContext = false;
+ bool pixelFormatFloat = false;
+ bool glColorSpace = false;
} EglExtensions;
EglManager::EglManager(RenderThread& thread)
: mRenderThread(thread)
, mEglDisplay(EGL_NO_DISPLAY)
, mEglConfig(nullptr)
+ , mEglConfigWideGamut(nullptr)
, mEglContext(EGL_NO_CONTEXT)
, mPBufferSurface(EGL_NO_SURFACE)
, mCurrentSurface(EGL_NO_SURFACE) {
@@ -116,7 +120,7 @@
}
}
- loadConfig();
+ loadConfigs();
createContext();
createPBufferSurface();
makeCurrent(mPBufferSurface);
@@ -143,6 +147,7 @@
void EglManager::initExtensions() {
auto extensions = StringUtils::split(
eglQueryString(mEglDisplay, EGL_EXTENSIONS));
+
// For our purposes we don't care if EGL_BUFFER_AGE is a result of
// EGL_EXT_buffer_age or EGL_KHR_partial_update as our usage is covered
// under EGL_KHR_partial_update and we don't need the expanded scope
@@ -152,13 +157,17 @@
EglExtensions.setDamage = extensions.has("EGL_KHR_partial_update");
LOG_ALWAYS_FATAL_IF(!extensions.has("EGL_KHR_swap_buffers_with_damage"),
"Missing required extension EGL_KHR_swap_buffers_with_damage");
+
+ EglExtensions.glColorSpace = extensions.has("EGL_KHR_gl_colorspace");
+ EglExtensions.noConfigContext = extensions.has("EGL_KHR_no_config_context");
+ EglExtensions.pixelFormatFloat = extensions.has("EGL_EXT_pixel_format_float");
}
bool EglManager::hasEglContext() {
return mEglDisplay != EGL_NO_DISPLAY;
}
-void EglManager::loadConfig() {
+void EglManager::loadConfigs() {
ALOGD("Swap behavior %d", static_cast<int>(mSwapBehavior));
EGLint swapBehavior = (mSwapBehavior == SwapBehavior::Preserved)
? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
@@ -175,19 +184,44 @@
EGL_NONE
};
- EGLint num_configs = 1;
- if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs)
- || num_configs != 1) {
+ EGLint numConfigs = 1;
+ if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, numConfigs, &numConfigs)
+ || numConfigs != 1) {
if (mSwapBehavior == SwapBehavior::Preserved) {
// Try again without dirty regions enabled
ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...");
mSwapBehavior = SwapBehavior::Discard;
- loadConfig();
+ loadConfigs();
+ return; // the call to loadConfigs() we just made picks the wide gamut config
} else {
// Failed to get a valid config
LOG_ALWAYS_FATAL("Failed to choose config, error = %s", eglErrorString());
}
}
+
+ if (EglExtensions.pixelFormatFloat) {
+ // If we reached this point, we have a valid swap behavior
+ EGLint attribs16F[] = {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+ EGL_RED_SIZE, 16,
+ EGL_GREEN_SIZE, 16,
+ EGL_BLUE_SIZE, 16,
+ EGL_ALPHA_SIZE, 16,
+ EGL_DEPTH_SIZE, 0,
+ EGL_STENCIL_SIZE, Stencil::getStencilSize(),
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
+ EGL_NONE
+ };
+
+ numConfigs = 1;
+ if (!eglChooseConfig(mEglDisplay, attribs16F, &mEglConfigWideGamut, numConfigs, &numConfigs)
+ || numConfigs != 1) {
+ LOG_ALWAYS_FATAL(
+ "Device claims wide gamut support, cannot find matching config, error = %s",
+ eglErrorString());
+ }
+ }
}
void EglManager::createContext() {
@@ -195,7 +229,9 @@
EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION,
EGL_NONE
};
- mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs);
+ mEglContext = eglCreateContext(mEglDisplay,
+ EglExtensions.noConfigContext ? ((EGLConfig) nullptr) : mEglConfig,
+ EGL_NO_CONTEXT, attribs);
LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT,
"Failed to create context, error = %s", eglErrorString());
}
@@ -210,18 +246,60 @@
}
}
-EGLSurface EglManager::createSurface(EGLNativeWindowType window) {
+EGLSurface EglManager::createSurface(EGLNativeWindowType window, bool wideColorGamut) {
initialize();
+ wideColorGamut = wideColorGamut && EglExtensions.glColorSpace
+ && EglExtensions.pixelFormatFloat && EglExtensions.noConfigContext;
+
+ // The color space we want to use depends on whether linear blending is turned
+ // on and whether the app has requested wide color gamut rendering. When wide
+ // color gamut rendering is off, the app simply renders in the display's native
+ // color gamut.
+ //
+ // When wide gamut rendering is off:
+ // - Blending is done by default in gamma space, which requires using a
+ // linear EGL color space (the GPU uses the color values as is)
+ // - If linear blending is on, we must use the sRGB EGL color space (the
+ // GPU will perform sRGB to linear and linear to SRGB conversions before
+ // and after blending)
+ //
+ // When wide gamut rendering is on we cannot rely on the GPU performing
+ // linear blending for us. We use two different color spaces to tag the
+ // surface appropriately for SurfaceFlinger:
+ // - Gamma blending (default) requires the use of the scRGB-nl color space
+ // - Linear blending requires the use of the scRGB color space
+
+ // Not all Android targets support the EGL_GL_COLOR_SPACE_KHR extension
+ // We insert to placeholders to set EGL_GL_COLORSPACE_KHR and its value.
+ // According to section 3.4.1 of the EGL specification, the attributes
+ // list is considered empty if the first entry is EGL_NONE
EGLint attribs[] = {
-#ifdef ANDROID_ENABLE_LINEAR_BLENDING
- EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR,
- EGL_COLORSPACE, EGL_COLORSPACE_sRGB,
-#endif
+ EGL_NONE, EGL_NONE,
EGL_NONE
};
- EGLSurface surface = eglCreateWindowSurface(mEglDisplay, mEglConfig, window, attribs);
+ if (EglExtensions.glColorSpace) {
+ attribs[0] = EGL_GL_COLORSPACE_KHR;
+#ifdef ANDROID_ENABLE_LINEAR_BLENDING
+ if (wideColorGamut) {
+ attribs[1] = EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT;
+ } else {
+ attribs[1] = EGL_GL_COLORSPACE_SRGB_KHR;
+ }
+#else
+ if (wideColorGamut) {
+ // TODO: this should be using scRGB-nl, not scRGB, we need an extension for this
+ // TODO: in the meantime SurfaceFlinger just assumes that scRGB is scRGB-nl
+ attribs[1] = EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT;
+ } else {
+ attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
+ }
+#endif
+ }
+
+ EGLSurface surface = eglCreateWindowSurface(mEglDisplay,
+ wideColorGamut ? mEglConfigWideGamut : mEglConfig, window, attribs);
LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE,
"Failed to create EGLSurface for window %p, eglErr = %s",
(void*) window, eglErrorString());
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index 0251925..2982c23 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -39,7 +39,7 @@
bool hasEglContext();
- EGLSurface createSurface(EGLNativeWindowType window);
+ EGLSurface createSurface(EGLNativeWindowType window, bool wideColorGamut);
void destroySurface(EGLSurface surface);
void destroy();
@@ -68,7 +68,7 @@
void initExtensions();
void createPBufferSurface();
- void loadConfig();
+ void loadConfigs();
void createContext();
EGLint queryBufferAge(EGLSurface surface);
@@ -76,6 +76,7 @@
EGLDisplay mEglDisplay;
EGLConfig mEglConfig;
+ EGLConfig mEglConfigWideGamut;
EGLContext mEglContext;
EGLSurface mPBufferSurface;
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 45f6718..46ac0d2 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -44,6 +44,12 @@
Succeeded
};
+enum class ColorMode {
+ Srgb,
+ WideColorGamut,
+ // Hdr
+};
+
class Frame;
class IRenderPipeline {
@@ -61,7 +67,7 @@
FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
virtual bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) = 0;
virtual DeferredLayerUpdater* createTextureLayer() = 0;
- virtual bool setSurface(Surface* window, SwapBehavior swapBehavior) = 0;
+ virtual bool setSurface(Surface* window, SwapBehavior swapBehavior, ColorMode colorMode) = 0;
virtual void onStop() = 0;
virtual bool isSurfaceReady() = 0;
virtual bool isContextReady() = 0;
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index e1ae585..e15d0eb 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -146,7 +146,7 @@
}
}
-bool OpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) {
+bool OpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior, ColorMode colorMode) {
if (mEglSurface != EGL_NO_SURFACE) {
mEglManager.destroySurface(mEglSurface);
@@ -154,7 +154,8 @@
}
if (surface) {
- mEglSurface = mEglManager.createSurface(surface);
+ const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
+ mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
}
if (mEglSurface != EGL_NO_SURFACE) {
@@ -267,6 +268,171 @@
thread.renderState().invokeFunctor(functor, mode, nullptr);
}
+#define FENCE_TIMEOUT 2000000000
+
+class AutoEglFence {
+public:
+ AutoEglFence(EGLDisplay display)
+ : mDisplay(display) {
+ fence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL);
+ }
+
+ ~AutoEglFence() {
+ if (fence != EGL_NO_SYNC_KHR) {
+ eglDestroySyncKHR(mDisplay, fence);
+ }
+ }
+
+ EGLSyncKHR fence = EGL_NO_SYNC_KHR;
+private:
+ EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoEglImage {
+public:
+ AutoEglImage(EGLDisplay display, EGLClientBuffer clientBuffer)
+ : mDisplay(display) {
+ EGLint imageAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+ image = eglCreateImageKHR(display, EGL_NO_CONTEXT,
+ EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
+ }
+
+ ~AutoEglImage() {
+ if (image != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(mDisplay, image);
+ }
+ }
+
+ EGLImageKHR image = EGL_NO_IMAGE_KHR;
+private:
+ EGLDisplay mDisplay = EGL_NO_DISPLAY;
+};
+
+class AutoGlTexture {
+public:
+ AutoGlTexture(uirenderer::Caches& caches)
+ : mCaches(caches) {
+ glGenTextures(1, &mTexture);
+ caches.textureState().bindTexture(mTexture);
+ }
+
+ ~AutoGlTexture() {
+ mCaches.textureState().deleteTexture(mTexture);
+ }
+
+private:
+ uirenderer::Caches& mCaches;
+ GLuint mTexture = 0;
+};
+
+static bool uploadBitmapToGraphicBuffer(uirenderer::Caches& caches, SkBitmap& bitmap,
+ GraphicBuffer& buffer, GLint format, GLint type) {
+ EGLDisplay display = eglGetCurrentDisplay();
+ LOG_ALWAYS_FATAL_IF(display == EGL_NO_DISPLAY,
+ "Failed to get EGL_DEFAULT_DISPLAY! err=%s",
+ uirenderer::renderthread::EglManager::eglErrorString());
+ // We use an EGLImage to access the content of the GraphicBuffer
+ // The EGL image is later bound to a 2D texture
+ EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer.getNativeBuffer();
+ AutoEglImage autoImage(display, clientBuffer);
+ if (autoImage.image == EGL_NO_IMAGE_KHR) {
+ ALOGW("Could not create EGL image, err =%s",
+ uirenderer::renderthread::EglManager::eglErrorString());
+ return false;
+ }
+ AutoGlTexture glTexture(caches);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, autoImage.image);
+
+ GL_CHECKPOINT(MODERATE);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
+ format, type, bitmap.getPixels());
+
+ GL_CHECKPOINT(MODERATE);
+
+ // The fence is used to wait for the texture upload to finish
+ // properly. We cannot rely on glFlush() and glFinish() as
+ // some drivers completely ignore these API calls
+ AutoEglFence autoFence(display);
+ if (autoFence.fence == EGL_NO_SYNC_KHR) {
+ LOG_ALWAYS_FATAL("Could not create sync fence %#x", eglGetError());
+ return false;
+ }
+ // The flag EGL_SYNC_FLUSH_COMMANDS_BIT_KHR will trigger a
+ // pipeline flush (similar to what a glFlush() would do.)
+ EGLint waitStatus = eglClientWaitSyncKHR(display, autoFence.fence,
+ EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, FENCE_TIMEOUT);
+ if (waitStatus != EGL_CONDITION_SATISFIED_KHR) {
+ LOG_ALWAYS_FATAL("Failed to wait for the fence %#x", eglGetError());
+ return false;
+ }
+ return true;
+}
+
+// TODO: handle SRGB sanely
+static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
+ switch (internalFormat) {
+ case GL_LUMINANCE:
+ return PIXEL_FORMAT_RGBA_8888;
+ case GL_SRGB8_ALPHA8:
+ return PIXEL_FORMAT_RGBA_8888;
+ case GL_RGBA:
+ return PIXEL_FORMAT_RGBA_8888;
+ case GL_RGB:
+ return PIXEL_FORMAT_RGB_565;
+ case GL_RGBA16F:
+ return PIXEL_FORMAT_RGBA_FP16;
+ default:
+ LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
+ return PIXEL_FORMAT_UNKNOWN;
+ }
+}
+
+sk_sp<Bitmap> OpenGLPipeline::allocateHardwareBitmap(RenderThread& renderThread,
+ SkBitmap& skBitmap) {
+ renderThread.eglManager().initialize();
+ uirenderer::Caches& caches = uirenderer::Caches::getInstance();
+
+ const SkImageInfo& info = skBitmap.info();
+ if (info.colorType() == kUnknown_SkColorType || info.colorType() == kAlpha_8_SkColorType) {
+ ALOGW("unable to create hardware bitmap of colortype: %d", info.colorType());
+ return nullptr;
+ }
+
+ bool needSRGB = uirenderer::transferFunctionCloseToSRGB(skBitmap.info().colorSpace());
+ bool hasLinearBlending = caches.extensions().hasLinearBlending();
+ GLint format, type, internalFormat;
+ uirenderer::Texture::colorTypeToGlFormatAndType(caches, skBitmap.colorType(),
+ needSRGB && hasLinearBlending, &internalFormat, &format, &type);
+
+ PixelFormat pixelFormat = internalFormatToPixelFormat(internalFormat);
+ sp<GraphicBuffer> buffer = new GraphicBuffer(info.width(), info.height(), pixelFormat,
+ GraphicBuffer::USAGE_HW_TEXTURE |
+ GraphicBuffer::USAGE_SW_WRITE_NEVER |
+ GraphicBuffer::USAGE_SW_READ_NEVER,
+ std::string("Bitmap::allocateHardwareBitmap pid [") + std::to_string(getpid()) + "]");
+
+ status_t error = buffer->initCheck();
+ if (error < 0) {
+ ALOGW("createGraphicBuffer() failed in GraphicBuffer.create()");
+ return nullptr;
+ }
+
+ SkBitmap bitmap;
+ if (CC_UNLIKELY(uirenderer::Texture::hasUnsupportedColorType(skBitmap.info(),
+ hasLinearBlending))) {
+ sk_sp<SkColorSpace> sRGB = SkColorSpace::MakeSRGB();
+ bitmap = uirenderer::Texture::uploadToN32(skBitmap, hasLinearBlending, std::move(sRGB));
+ } else {
+ bitmap = skBitmap;
+ }
+
+ if (!uploadBitmapToGraphicBuffer(caches, bitmap, *buffer, format, type)) {
+ return nullptr;
+ }
+ return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info()));
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/OpenGLPipeline.h b/libs/hwui/renderthread/OpenGLPipeline.h
index 6df8be4..0e8c3f5 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.h
+++ b/libs/hwui/renderthread/OpenGLPipeline.h
@@ -44,7 +44,7 @@
FrameInfo* currentFrameInfo, bool* requireSwap) override;
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) override;
DeferredLayerUpdater* createTextureLayer() override;
- bool setSurface(Surface* window, SwapBehavior swapBehavior) override;
+ bool setSurface(Surface* window, SwapBehavior swapBehavior, ColorMode colorMode) override;
void onStop() override;
bool isSurfaceReady() override;
bool isContextReady() override;
@@ -61,6 +61,8 @@
static void destroyLayer(RenderNode* node);
static void prepareToDraw(const RenderThread& thread, Bitmap* bitmap);
static void invokeFunctor(const RenderThread& thread, Functor* functor);
+ static sk_sp<Bitmap> allocateHardwareBitmap(RenderThread& thread,
+ SkBitmap& skBitmap);
private:
EglManager& mEglManager;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index eed5238..5a4695f 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -227,6 +227,18 @@
post(task);
}
+CREATE_BRIDGE2(setWideGamut, CanvasContext* context, bool wideGamut) {
+ args->context->setWideGamut(args->wideGamut);
+ return nullptr;
+}
+
+void RenderProxy::setWideGamut(bool wideGamut) {
+ SETUP_TASK(setWideGamut);
+ args->context = mContext;
+ args->wideGamut = wideGamut;
+ post(task);
+}
+
int64_t* RenderProxy::frameInfo() {
return mDrawFrameTask.frameInfo();
}
@@ -664,7 +676,7 @@
}
CREATE_BRIDGE2(allocateHardwareBitmap, RenderThread* thread, SkBitmap* bitmap) {
- sk_sp<Bitmap> hardwareBitmap = Bitmap::allocateHardwareBitmap(*args->thread, *args->bitmap);
+ sk_sp<Bitmap> hardwareBitmap = args->thread->allocateHardwareBitmap(*args->bitmap);
return hardwareBitmap.release();
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index b21772c..e1e2808 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -69,7 +69,7 @@
*/
class ANDROID_API RenderProxy {
public:
- ANDROID_API RenderProxy(bool translucent, RenderNode* rootNode, IContextFactory* contextFactory);
+ ANDROID_API RenderProxy(bool opaque, RenderNode* rootNode, IContextFactory* contextFactory);
ANDROID_API virtual ~RenderProxy();
// Won't take effect until next EGLSurface creation
@@ -85,6 +85,7 @@
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
ANDROID_API void setLightCenter(const Vector3& lightCenter);
ANDROID_API void setOpaque(bool opaque);
+ ANDROID_API void setWideGamut(bool wideGamut);
ANDROID_API int64_t* frameInfo();
ANDROID_API int syncAndDrawFrame();
ANDROID_API void destroy();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 1450ec9..0554583 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -16,8 +16,12 @@
#include "RenderThread.h"
-#include "../renderstate/RenderState.h"
-#include "../pipeline/skia/SkiaOpenGLReadback.h"
+#include "hwui/Bitmap.h"
+#include "renderstate/RenderState.h"
+#include "renderthread/OpenGLPipeline.h"
+#include "pipeline/skia/SkiaOpenGLReadback.h"
+#include "pipeline/skia/SkiaOpenGLPipeline.h"
+#include "pipeline/skia/SkiaVulkanPipeline.h"
#include "CanvasContext.h"
#include "EglManager.h"
#include "OpenGLReadback.h"
@@ -433,6 +437,22 @@
return next;
}
+sk_sp<Bitmap> RenderThread::allocateHardwareBitmap(SkBitmap& skBitmap) {
+ auto renderType = Properties::getRenderPipelineType();
+ switch (renderType) {
+ case RenderPipelineType::OpenGL:
+ return OpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
+ case RenderPipelineType::SkiaGL:
+ return skiapipeline::SkiaOpenGLPipeline::allocateHardwareBitmap(*this, skBitmap);
+ case RenderPipelineType::SkiaVulkan:
+ return skiapipeline::SkiaVulkanPipeline::allocateHardwareBitmap(*this, skBitmap);
+ default:
+ LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType);
+ break;
+ }
+ return nullptr;
+}
+
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 9bc5985..4b5601c 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -24,6 +24,7 @@
#include <GrContext.h>
#include <cutils/compiler.h>
+#include <SkBitmap.h>
#include <ui/DisplayInfo.h>
#include <utils/Looper.h>
#include <utils/Thread.h>
@@ -33,6 +34,7 @@
namespace android {
+class Bitmap;
class DisplayEventReceiver;
namespace uirenderer {
@@ -104,6 +106,8 @@
VulkanManager& vulkanManager() { return *mVkManager; }
+ sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& skBitmap);
+
protected:
virtual bool threadLoop() override;
diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
index a7ebb68..4797dec 100644
--- a/libs/hwui/tests/common/scenes/BitmapShaders.cpp
+++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
@@ -45,10 +45,8 @@
skCanvas.drawRect(SkRect::MakeXYWH(100, 100, 100, 100), skPaint);
});
- SkBitmap bitmap;
SkPaint paint;
- hwuiBitmap->getSkBitmapForShaders(&bitmap);
- sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
+ sk_sp<SkImage> image = hwuiBitmap->makeImage();
sk_sp<SkShader> repeatShader = image->makeShader(
SkShader::TileMode::kRepeat_TileMode,
SkShader::TileMode::kRepeat_TileMode,
diff --git a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
index a461426..c246eba 100644
--- a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
+++ b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
@@ -75,9 +75,7 @@
void doFrame(int frameNr) override { }
sk_sp<SkShader> createBitmapShader(Bitmap& bitmap) {
- SkBitmap skBitmap;
- bitmap.getSkBitmapForShaders(&skBitmap);
- sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode);
+ sk_sp<SkImage> image = bitmap.makeImage();
return image->makeShader(SkShader::TileMode::kClamp_TileMode,
SkShader::TileMode::kClamp_TileMode);
}
diff --git a/libs/hwui/tests/unit/TextureCacheTests.cpp b/libs/hwui/tests/unit/TextureCacheTests.cpp
index 72384bf..ab740dd 100644
--- a/libs/hwui/tests/unit/TextureCacheTests.cpp
+++ b/libs/hwui/tests/unit/TextureCacheTests.cpp
@@ -31,7 +31,7 @@
SkBitmap skBitmap;
SkImageInfo info = SkImageInfo::Make(100, 100, kN32_SkColorType, kPremul_SkAlphaType);
skBitmap.setInfo(info);
- sk_sp<Bitmap> hwBitmap(Bitmap::allocateHardwareBitmap(renderThread, skBitmap));
+ sk_sp<Bitmap> hwBitmap(renderThread.allocateHardwareBitmap(skBitmap));
cache.get(hwBitmap.get());
ASSERT_EQ(GpuMemoryTracker::getInstanceCount(GpuObjectType::Texture), initialCount + 1);
cache.clear();
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index d2d4b5b..9b74656 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -339,6 +339,12 @@
(unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td>
</tr>
<tr>
+ <td>FLAC</td>
+ <td>Metadata blocks</td>
+ <td class=NA>Not Used</td>
+ <td class=NA>Not Used</td>
+ </tr>
+ <tr>
<td>MPEG-4</td>
<td>Decoder-specific information from ESDS<sup>*</sup></td>
<td class=NA>Not Used</td>
diff --git a/media/jni/soundpool/SoundPoolThread.cpp b/media/jni/soundpool/SoundPoolThread.cpp
index ba3b482..3d98877 100644
--- a/media/jni/soundpool/SoundPoolThread.cpp
+++ b/media/jni/soundpool/SoundPoolThread.cpp
@@ -20,6 +20,8 @@
#include "SoundPoolThread.h"
+static const int kMaxWorkers = 3;
+
namespace android {
void SoundPoolThread::write(SoundPoolMsg msg) {
@@ -31,14 +33,21 @@
// if thread is quitting, don't add to queue
if (mRunning) {
mMsgQueue.push(msg);
- mCondition.signal();
+ if (mNumWorkers < kMaxWorkers) {
+ if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
+ mNumWorkers++;
+ ALOGV("created worker thread");
+ }
+ }
}
}
const SoundPoolMsg SoundPoolThread::read() {
Mutex::Autolock lock(&mLock);
- while (mMsgQueue.size() == 0) {
- mCondition.wait(mLock);
+ if (mMsgQueue.size() == 0) {
+ mNumWorkers--;
+ mCondition.signal();
+ return SoundPoolMsg(SoundPoolMsg::KILL, 0);
}
SoundPoolMsg msg = mMsgQueue[0];
mMsgQueue.removeAt(0);
@@ -51,20 +60,20 @@
if (mRunning) {
mRunning = false;
mMsgQueue.clear();
- mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0));
- mCondition.signal();
- mCondition.wait(mLock);
+ mCondition.broadcast(); // wake up any blocked writers
+ while (mNumWorkers > 0) {
+ mCondition.wait(mLock);
+ }
}
ALOGV("return from quit");
}
SoundPoolThread::SoundPoolThread(SoundPool* soundPool) :
- mSoundPool(soundPool)
+ mSoundPool(soundPool),
+ mNumWorkers(0),
+ mRunning(true)
{
mMsgQueue.setCapacity(maxMessages);
- if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
- mRunning = true;
- }
}
SoundPoolThread::~SoundPoolThread()
diff --git a/media/jni/soundpool/SoundPoolThread.h b/media/jni/soundpool/SoundPoolThread.h
index 7b3e1dd..5d7bf0c 100644
--- a/media/jni/soundpool/SoundPoolThread.h
+++ b/media/jni/soundpool/SoundPoolThread.h
@@ -58,6 +58,7 @@
Condition mCondition;
Vector<SoundPoolMsg> mMsgQueue;
SoundPool* mSoundPool;
+ int32_t mNumWorkers;
bool mRunning;
};
diff --git a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
deleted file mode 100644
index b237021..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.settingslib;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.os.AsyncTask;
-import android.os.BatteryManager;
-import android.os.BatteryStats;
-import android.os.BatteryStats.HistoryItem;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.text.format.Formatter;
-import android.util.SparseIntArray;
-import com.android.internal.os.BatteryStatsHelper;
-import com.android.settingslib.graph.UsageView;
-
-public class BatteryInfo {
-
- public String chargeLabelString;
- public int batteryLevel;
- public boolean discharging = true;
- public long remainingTimeUs = 0;
- public String batteryPercentString;
- public String remainingLabel;
- public String statusLabel;
- private boolean mCharging;
- private BatteryStats mStats;
- private long timePeriod;
-
- public interface Callback {
- void onBatteryInfoLoaded(BatteryInfo info);
- }
-
- public void bindHistory(final UsageView view, BatteryDataParser... parsers) {
- BatteryDataParser parser = new BatteryDataParser() {
- SparseIntArray points = new SparseIntArray();
-
- @Override
- public void onParsingStarted(long startTime, long endTime) {
- timePeriod = endTime - startTime - remainingTimeUs / 1000;
- view.clearPaths();
- view.configureGraph((int) (endTime - startTime), 100, remainingTimeUs != 0,
- mCharging);
- }
-
- @Override
- public void onDataPoint(long time, HistoryItem record) {
- points.put((int) time, record.batteryLevel);
- }
-
- @Override
- public void onDataGap() {
- if (points.size() > 1) {
- view.addPath(points);
- }
- points.clear();
- }
-
- @Override
- public void onParsingDone() {
- if (points.size() > 1) {
- view.addPath(points);
- }
- }
- };
- BatteryDataParser[] parserList = new BatteryDataParser[parsers.length + 1];
- for (int i = 0; i < parsers.length; i++) {
- parserList[i] = parsers[i];
- }
- parserList[parsers.length] = parser;
- parse(mStats, remainingTimeUs, parserList);
- final Context context = view.getContext();
- String timeString = context.getString(R.string.charge_length_format,
- Formatter.formatShortElapsedTime(context, timePeriod));
- String remaining = "";
- if (remainingTimeUs != 0) {
- remaining = context.getString(R.string.remaining_length_format,
- Formatter.formatShortElapsedTime(context, remainingTimeUs / 1000));
- }
- view.setBottomLabels(new CharSequence[]{timeString, remaining});
- }
-
- public static void getBatteryInfo(final Context context, final Callback callback) {
- BatteryInfo.getBatteryInfo(context, callback, false /* shortString */);
- }
-
- public static void getBatteryInfo(final Context context, final Callback callback,
- boolean shortString) {
- new AsyncTask<Void, Void, BatteryStats>() {
- @Override
- protected BatteryStats doInBackground(Void... params) {
- BatteryStatsHelper statsHelper = new BatteryStatsHelper(context, true);
- statsHelper.create((Bundle) null);
- return statsHelper.getStats();
- }
-
- @Override
- protected void onPostExecute(BatteryStats batteryStats) {
- final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
- Intent batteryBroadcast = context.registerReceiver(null,
- new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
- BatteryInfo batteryInfo = BatteryInfo.getBatteryInfo(context, batteryBroadcast,
- batteryStats, elapsedRealtimeUs, shortString);
- callback.onBatteryInfoLoaded(batteryInfo);
- }
- }.execute();
- }
-
- public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
- BatteryStats stats, long elapsedRealtimeUs) {
- return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, elapsedRealtimeUs,
- false /* shortString */);
- }
-
- public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
- BatteryStats stats, long elapsedRealtimeUs, boolean shortString) {
- return getBatteryInfo(context, batteryBroadcast, stats, elapsedRealtimeUs, shortString,
- stats.computeBatteryTimeRemaining(elapsedRealtimeUs), false);
- }
-
- public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast,
- BatteryStats stats, long elapsedRealtimeUs, boolean shortString, long drainTimeUs,
- boolean basedOnUsage) {
- BatteryInfo info = new BatteryInfo();
- info.mStats = stats;
- info.batteryLevel = Utils.getBatteryLevel(batteryBroadcast);
- info.batteryPercentString = Utils.formatPercentage(info.batteryLevel);
- info.mCharging = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
- final Resources resources = context.getResources();
-
- info.statusLabel = Utils.getBatteryStatus(resources, batteryBroadcast);
- if (!info.mCharging) {
- if (drainTimeUs > 0) {
- info.remainingTimeUs = drainTimeUs;
- String timeString = Formatter.formatShortElapsedTime(context,
- drainTimeUs / 1000);
- info.remainingLabel = resources.getString(
- shortString ?
- (basedOnUsage ?
- R.string.power_remaining_duration_only_short_enhanced :
- R.string.power_remaining_duration_only_short) :
- (basedOnUsage ?
- R.string.power_remaining_duration_only_enhanced :
- R.string.power_remaining_duration_only),
- timeString);
- info.chargeLabelString = resources.getString(
- shortString ?
- R.string.power_discharging_duration_short :
- basedOnUsage ?
- R.string.power_discharging_duration_enhanced :
- R.string.power_discharging_duration,
- info.batteryPercentString, timeString);
- } else {
- info.remainingLabel = null;
- info.chargeLabelString = info.batteryPercentString;
- }
- } else {
- final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs);
- final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS,
- BatteryManager.BATTERY_STATUS_UNKNOWN);
- info.discharging = false;
- if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) {
- info.remainingTimeUs = chargeTime;
- String timeString = Formatter.formatShortElapsedTime(context,
- chargeTime / 1000);
- int resId = shortString ? R.string.power_charging_duration_short
- : R.string.power_charging_duration;
- info.remainingLabel = resources.getString(
- R.string.power_remaining_charging_duration_only, timeString);
- info.chargeLabelString = resources.getString(
- resId, info.batteryPercentString, timeString);
- } else {
- final String chargeStatusLabel = resources.getString(
- R.string.battery_info_status_charging_lower);
- info.remainingLabel = null;
- info.chargeLabelString = resources.getString(
- R.string.power_charging, info.batteryPercentString, chargeStatusLabel);
- }
- }
- return info;
- }
-
- public interface BatteryDataParser {
- void onParsingStarted(long startTime, long endTime);
-
- void onDataPoint(long time, HistoryItem record);
-
- void onDataGap();
-
- void onParsingDone();
- }
-
- private static void parse(BatteryStats stats, long remainingTimeUs,
- BatteryDataParser... parsers) {
- long startWalltime = 0;
- long endDateWalltime = 0;
- long endWalltime = 0;
- long historyStart = 0;
- long historyEnd = 0;
- byte lastLevel = -1;
- long curWalltime = startWalltime;
- long lastWallTime = 0;
- long lastRealtime = 0;
- int lastInteresting = 0;
- int pos = 0;
- boolean first = true;
- if (stats.startIteratingHistoryLocked()) {
- final HistoryItem rec = new HistoryItem();
- while (stats.getNextHistoryLocked(rec)) {
- pos++;
- if (first) {
- first = false;
- historyStart = rec.time;
- }
- if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
- || rec.cmd == HistoryItem.CMD_RESET) {
- // If there is a ridiculously large jump in time, then we won't be
- // able to create a good chart with that data, so just ignore the
- // times we got before and pretend like our data extends back from
- // the time we have now.
- // Also, if we are getting a time change and we are less than 5 minutes
- // since the start of the history real time, then also use this new
- // time to compute the base time, since whatever time we had before is
- // pretty much just noise.
- if (rec.currentTime > (lastWallTime + (180 * 24 * 60 * 60 * 1000L))
- || rec.time < (historyStart + (5 * 60 * 1000L))) {
- startWalltime = 0;
- }
- lastWallTime = rec.currentTime;
- lastRealtime = rec.time;
- if (startWalltime == 0) {
- startWalltime = lastWallTime - (lastRealtime - historyStart);
- }
- }
- if (rec.isDeltaData()) {
- if (rec.batteryLevel != lastLevel || pos == 1) {
- lastLevel = rec.batteryLevel;
- }
- lastInteresting = pos;
- historyEnd = rec.time;
- }
- }
- }
- stats.finishIteratingHistoryLocked();
- endDateWalltime = lastWallTime + historyEnd - lastRealtime;
- endWalltime = endDateWalltime + (remainingTimeUs / 1000);
-
- int i = 0;
- final int N = lastInteresting;
-
- for (int j = 0; j < parsers.length; j++) {
- parsers[j].onParsingStarted(startWalltime, endWalltime);
- }
- if (endDateWalltime > startWalltime && stats.startIteratingHistoryLocked()) {
- final HistoryItem rec = new HistoryItem();
- while (stats.getNextHistoryLocked(rec) && i < N) {
- if (rec.isDeltaData()) {
- curWalltime += rec.time - lastRealtime;
- lastRealtime = rec.time;
- long x = (curWalltime - startWalltime);
- if (x < 0) {
- x = 0;
- }
- for (int j = 0; j < parsers.length; j++) {
- parsers[j].onDataPoint(x, rec);
- }
- } else {
- long lastWalltime = curWalltime;
- if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
- || rec.cmd == HistoryItem.CMD_RESET) {
- if (rec.currentTime >= startWalltime) {
- curWalltime = rec.currentTime;
- } else {
- curWalltime = startWalltime + (rec.time - historyStart);
- }
- lastRealtime = rec.time;
- }
-
- if (rec.cmd != HistoryItem.CMD_OVERFLOW
- && (rec.cmd != HistoryItem.CMD_CURRENT_TIME
- || Math.abs(lastWalltime - curWalltime) > (60 * 60 * 1000))) {
- for (int j = 0; j < parsers.length; j++) {
- parsers[j].onDataGap();
- }
- }
- }
- i++;
- }
- }
-
- stats.finishIteratingHistoryLocked();
-
- for (int j = 0; j < parsers.length; j++) {
- parsers[j].onParsingDone();
- }
- }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index 7f95379..5361b43 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -63,6 +63,7 @@
private int mWifiBadge = NetworkBadging.BADGING_NONE;
static final int[] WIFI_CONNECTION_STRENGTH = {
+ R.string.accessibility_no_wifi,
R.string.accessibility_wifi_one_bar,
R.string.accessibility_wifi_two_bars,
R.string.accessibility_wifi_three_bars,
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiSavedConfigUtils.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiSavedConfigUtils.java
new file mode 100644
index 0000000..159b2a1
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiSavedConfigUtils.java
@@ -0,0 +1,67 @@
+/*
+ * 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.settingslib.wifi;
+
+import android.content.Context;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provide utility functions for retrieving saved Wi-Fi configurations.
+ */
+public class WifiSavedConfigUtils {
+ /**
+ * Returns all the saved configurations on the device, including both Wi-Fi networks and
+ * Passpoint profiles, represented by {@link AccessPoint}.
+ *
+ * @param context The application context
+ * @param wifiManager An instance of {@link WifiManager}
+ * @return List of {@link AccessPoint}
+ */
+ public static List<AccessPoint> getAllConfigs(Context context, WifiManager wifiManager) {
+ List<AccessPoint> savedConfigs = new ArrayList<>();
+ List<WifiConfiguration> savedNetworks = wifiManager.getConfiguredNetworks();
+ for (WifiConfiguration network : savedNetworks) {
+ // Configuration for Passpoint network is configured temporary by WifiService for
+ // connection attempt only. The underlying configuration is saved as Passpoint
+ // configuration, which will be retrieved with WifiManager#getPasspointConfiguration
+ // call below.
+ if (network.isPasspoint()) {
+ continue;
+ }
+ // Ephemeral networks are not saved to the persistent storage, ignore them.
+ if (network.isEphemeral()) {
+ continue;
+ }
+ savedConfigs.add(new AccessPoint(context, network));
+ }
+ try {
+ List<PasspointConfiguration> savedPasspointConfigs =
+ wifiManager.getPasspointConfigurations();
+ for (PasspointConfiguration config : savedPasspointConfigs) {
+ savedConfigs.add(new AccessPoint(context, config));
+ }
+ } catch (UnsupportedOperationException e) {
+ // Passpoint not supported.
+ }
+ return savedConfigs;
+ }
+}
+
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 7a63b8a..20cc5a6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -95,8 +95,6 @@
private WifiTrackerNetworkCallback mNetworkCallback;
- private int mNumSavedNetworks;
-
@GuardedBy("mLock")
private boolean mRegistered;
@@ -399,9 +397,11 @@
/**
* Returns the number of saved networks on the device, regardless of whether the WifiTracker
* is tracking saved networks.
+ * TODO(b/62292448): remove this function and update callsites to use WifiSavedConfigUtils
+ * directly.
*/
public int getNumSavedNetworks() {
- return mNumSavedNetworks;
+ return WifiSavedConfigUtils.getAllConfigs(mContext, mWifiManager).size();
}
public boolean isConnected() {
@@ -499,12 +499,10 @@
final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
if (configs != null) {
- mNumSavedNetworks = 0;
for (WifiConfiguration config : configs) {
if (config.selfAdded && config.numAssociation == 0) {
continue;
}
- mNumSavedNetworks++;
AccessPoint accessPoint = getCachedOrCreate(config, cachedAccessPoints);
if (mLastInfo != null && mLastNetworkInfo != null) {
accessPoint.update(connectionConfig, mLastInfo, mLastNetworkInfo);
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index d4ce40c..086e10c 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -410,6 +410,7 @@
validConfig.BSSID = BSSID_1;
WifiConfiguration selfAddedNoAssociation = new WifiConfiguration();
+ selfAddedNoAssociation.ephemeral = true;
selfAddedNoAssociation.selfAdded = true;
selfAddedNoAssociation.numAssociation = 0;
selfAddedNoAssociation.SSID = SSID_2;
@@ -746,4 +747,4 @@
verifyNoMoreInteractions(mockWifiListener);
}
-}
\ No newline at end of file
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
deleted file mode 100644
index cffece4..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/BatteryInfoTest.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.BatteryManager;
-import android.os.BatteryStats;
-import android.os.SystemClock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.AdditionalMatchers;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.AdditionalMatchers.*;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.when;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class BatteryInfoTest {
- private static final String STATUS_FULL = "Full";
- private static final String STATUS_CHARGING_NO_TIME = "Charging";
- private static final String STATUS_CHARGING_TIME = "Charging - 2h left";
- private static final int PLUGGED_IN = 1;
- private static final long REMAINING_TIME_NULL = -1;
- private static final long REMAINING_TIME = 2;
- public static final String ENHANCED_STRING_SUFFIX = "left based on your usage";
- private Intent mDisChargingBatteryBroadcast;
- private Intent mChargingBatteryBroadcast;
- private Context mRealContext;
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private BatteryStats mBatteryStats;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Resources mResources;
-
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mDisChargingBatteryBroadcast = new Intent();
- mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_PLUGGED, 0);
- mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 0);
- mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_SCALE, 100);
- mDisChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_STATUS,
- BatteryManager.BATTERY_STATUS_FULL);
-
- mChargingBatteryBroadcast = new Intent();
- mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_PLUGGED,
- BatteryManager.BATTERY_PLUGGED_AC);
- mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_LEVEL, 50);
- mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_SCALE, 100);
- mChargingBatteryBroadcast.putExtra(BatteryManager.EXTRA_STATUS,
- BatteryManager.BATTERY_STATUS_UNKNOWN);
-
- when(mContext.getResources().getString(R.string.battery_info_status_full))
- .thenReturn(STATUS_FULL);
- when(mContext.getResources().getString(eq(R.string.power_charging), any(),
- any())).thenReturn(STATUS_CHARGING_NO_TIME);
- when(mContext.getResources().getString(eq(R.string.power_charging_duration), any(),
- any())).thenReturn(STATUS_CHARGING_TIME);
- mRealContext = RuntimeEnvironment.application;
- }
-
- @Test
- public void testGetBatteryInfo_hasStatusLabel() {
- doReturn(REMAINING_TIME_NULL).when(mBatteryStats).computeBatteryTimeRemaining(anyLong());
- BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
- mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */);
-
- assertThat(info.statusLabel).isEqualTo(STATUS_FULL);
- }
-
- @Test
- public void testGetBatteryInfo_doNotShowChargingMethod_hasRemainingTime() {
- doReturn(REMAINING_TIME).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
- BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
- mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */);
-
- assertThat(info.chargeLabelString).isEqualTo(STATUS_CHARGING_TIME);
- }
-
- @Test
- public void testGetBatteryInfo_doNotShowChargingMethod_noRemainingTime() {
- doReturn(REMAINING_TIME_NULL).when(mBatteryStats).computeChargeTimeRemaining(anyLong());
- BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
- mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */);
-
- assertThat(info.chargeLabelString).isEqualTo(STATUS_CHARGING_NO_TIME);
- }
-
- @Test
- public void testGetBatteryInfo_pluggedIn_dischargingFalse() {
- BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mChargingBatteryBroadcast,
- mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */);
-
- assertThat(info.discharging).isEqualTo(false);
- }
-
- @Test
- public void testGetBatteryInfo_basedOnUsageTrue_usesUsageString() {
- doReturn(mResources).when(mContext).getResources();
- when(mResources.getString(eq(R.string.battery_info_status_full))).thenReturn("");
- when(mResources.getString(eq(R.string.power_remaining_duration_only_enhanced), any()))
- .thenReturn(ENHANCED_STRING_SUFFIX);
- when(mResources.getString(eq(R.string.power_remaining_duration_only_short_enhanced), any()))
- .thenReturn(ENHANCED_STRING_SUFFIX);
- BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
- mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */,
- 1000, true /* basedOnUsage */);
- BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
- mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */,
- 1000, true /* basedOnUsage */);
-
- assertThat(info.remainingLabel).contains(ENHANCED_STRING_SUFFIX);
- assertThat(info2.remainingLabel).contains(ENHANCED_STRING_SUFFIX);
- }
-
- @Test
- public void testGetBatteryInfo_basedOnUsageFalse_usesDefaultString() {
- doReturn(mResources).when(mContext).getResources();
- when(mResources.getString(eq(R.string.battery_info_status_full))).thenReturn("");
- when(mResources.getString(not(eq(R.string.power_remaining_duration_only_enhanced)), any()))
- .thenReturn(ENHANCED_STRING_SUFFIX);
- when(mResources.getString(not(eq(R.string.power_remaining_duration_only_short_enhanced)),
- any())).thenReturn("");
- BatteryInfo info = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
- mBatteryStats, SystemClock.elapsedRealtime() * 1000, false /* shortString */,
- 1000, false /* basedOnUsage */);
- BatteryInfo info2 = BatteryInfo.getBatteryInfo(mContext, mDisChargingBatteryBroadcast,
- mBatteryStats, SystemClock.elapsedRealtime() * 1000, true /* shortString */,
- 1000, false /* basedOnUsage */);
-
- assertThat(info.remainingLabel).doesNotContain(ENHANCED_STRING_SUFFIX);
- assertThat(info2.remainingLabel).doesNotContain(ENHANCED_STRING_SUFFIX);
- }
-}
diff --git a/packages/Shell/src/com/android/shell/Screenshooter.java b/packages/Shell/src/com/android/shell/Screenshooter.java
index 92c5fcc..8e27edf 100644
--- a/packages/Shell/src/com/android/shell/Screenshooter.java
+++ b/packages/Shell/src/com/android/shell/Screenshooter.java
@@ -100,7 +100,7 @@
// Rotate the screenshot to the current orientation
if (rotation != ROTATION_FREEZE_0) {
Bitmap unrotatedScreenShot = Bitmap.createBitmap(displayWidth, displayHeight,
- Bitmap.Config.ARGB_8888);
+ Bitmap.Config.ARGB_8888, screenShot.hasAlpha(), screenShot.getColorSpace());
Canvas canvas = new Canvas(unrotatedScreenShot);
canvas.translate(unrotatedScreenShot.getWidth() / 2,
unrotatedScreenShot.getHeight() / 2);
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 3ee451a..e322acc 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -195,6 +195,9 @@
<!-- to access instant apps -->
<uses-permission android:name="android.permission.ACCESS_INSTANT_APPS" />
+ <!-- to change themes - light or dark -->
+ <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
+
<application
android:name=".SystemUIApplication"
android:persistent="true"
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml b/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
index 84ccb7c..fd385fc 100644
--- a/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
+++ b/packages/SystemUI/res-keyguard/drawable/ic_access_alarms_big.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -18,8 +18,7 @@
android:height="18dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
-
<path
- android:fillColor="@color/clock_gray"
- android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+ android:fillColor="?attr/bgProtectSecondaryTextColor"
+ android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM7.24,2.63a1,1 0,0 0,-1.41 -0.13L2.77,5.07A0.996,0.996 0,1 0,4.05 6.6l3.06,-2.57c0.43,-0.35 0.48,-0.98 0.13,-1.4zM11.75,8c-0.41,0 -0.75,0.34 -0.75,0.75v4.68c0,0.35 0.18,0.68 0.49,0.86l3.65,2.19c0.34,0.2 0.78,0.1 0.98,-0.24a0.71,0.71 0,0 0,-0.25 -0.99l-3.37,-2v-4.5c0,-0.41 -0.34,-0.75 -0.75,-0.75zM12,5.9c-3.91,0 -7.1,3.18 -7.1,7.1s3.19,7.1 7.1,7.1 7.1,-3.18 7.1,-7.1 -3.19,-7.1 -7.1,-7.1M12,4a9,9 0,1 1,-0.001 18.001A9,9 0,0 1,12 4z" />
</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/pin_divider.xml b/packages/SystemUI/res-keyguard/drawable/pin_divider.xml
new file mode 100644
index 0000000..39104b5
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/pin_divider.xml
@@ -0,0 +1,20 @@
+<?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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="@color/pin_divider_color" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
index 29c93d5..26a179a 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
@@ -54,6 +54,7 @@
android:textStyle="normal"
android:inputType="textPassword"
android:textSize="16sp"
+ android:textColor="?attr/bgProtectTextColor"
android:textAppearance="?android:attr/textAppearanceMedium"
android:imeOptions="flagForceAscii|actionDone"
android:maxLength="500"
@@ -67,6 +68,7 @@
android:contentDescription="@string/accessibility_ime_switch_button"
android:clickable="true"
android:padding="8dip"
+ android:tint="@color/background_protected"
android:layout_gravity="end|center_vertical"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index e75f3c15..9a97162 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -54,6 +54,7 @@
android:layout_centerHorizontal="true"
android:layout_marginRight="72dp"
androidprv:scaledTextSize="28"
+ android:textColor="?attr/bgProtectTextColor"
android:contentDescription="@string/keyguard_accessibility_pin_area"
/>
<ImageButton
@@ -65,19 +66,20 @@
android:clickable="true"
android:paddingTop="8dip"
android:paddingBottom="8dip"
- android:paddingRight="8dp"
+ android:paddingRight="0dp"
android:paddingLeft="24dp"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_delete"
android:layout_alignEnd="@+id/pinEntry"
android:layout_alignParentRight="true"
+ android:tint="@color/pin_delete_color"
/>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
- android:background="#28FFFFFF"
+ android:background="@drawable/pin_divider"
/>
</com.android.keyguard.AlphaOptimizedRelativeLayout>
<LinearLayout
@@ -203,6 +205,7 @@
android:layout_weight="1"
android:paddingBottom="11sp"
android:src="@drawable/ic_done_wht"
+ style="@style/Keyguard.ImageButton.NumPadEnter"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_enter"
/>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index 920498f..87b1ee7 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -41,7 +41,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
- android:textColor="@color/clock_white"
+ android:textColor="?attr/bgProtectTextColor"
android:singleLine="true"
style="@style/widget_big_thin"
android:format12Hour="@string/keyguard_widget_12_hours_format"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
index fd681ca..7d47881 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
@@ -66,6 +66,7 @@
android:layout_centerHorizontal="true"
android:layout_marginRight="72dp"
androidprv:scaledTextSize="28"
+ android:textColor="?attr/bgProtectTextColor"
android:contentDescription="@string/keyguard_accessibility_sim_pin_area"
/>
<ImageButton
@@ -77,19 +78,20 @@
android:clickable="true"
android:paddingTop="8dip"
android:paddingBottom="8dip"
- android:paddingRight="8dp"
+ android:paddingRight="0dp"
android:paddingLeft="24dp"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_delete"
android:layout_alignEnd="@+id/pinEntry"
android:layout_alignParentRight="true"
+ android:tint="@color/pin_delete_color"
/>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
- android:background="#28FFFFFF"
+ android:background="@drawable/pin_divider"
/>
</RelativeLayout>
<LinearLayout
@@ -211,6 +213,7 @@
android:layout_weight="1"
android:paddingBottom="11sp"
android:src="@drawable/ic_done_wht"
+ style="@style/Keyguard.ImageButton.NumPadEnter"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_enter"
/>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
index 040b429..aaa53ee 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
@@ -67,6 +67,7 @@
android:layout_centerHorizontal="true"
android:layout_marginRight="72dp"
androidprv:scaledTextSize="28"
+ android:textColor="?attr/bgProtectTextColor"
android:contentDescription="@string/keyguard_accessibility_sim_puk_area"
/>
<ImageButton
@@ -78,19 +79,20 @@
android:clickable="true"
android:paddingTop="8dip"
android:paddingBottom="8dip"
- android:paddingRight="8dp"
+ android:paddingRight="0dp"
android:paddingLeft="24dp"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_delete"
android:layout_alignEnd="@+id/pinEntry"
android:layout_alignParentRight="true"
+ android:tint="@color/pin_delete_color"
/>
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentBottom="true"
- android:background="#28FFFFFF"
+ android:background="@drawable/pin_divider"
/>
</RelativeLayout>
<LinearLayout
@@ -212,6 +214,7 @@
android:layout_weight="1"
android:paddingBottom="11sp"
android:src="@drawable/ic_done_wht"
+ style="@style/Keyguard.ImageButton.NumPadEnter"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/keyboardview_keycode_enter"
/>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
index ed415b8..a0850f4 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
@@ -25,10 +25,11 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
- <TextClock android:id="@+id/date_view"
+ <com.android.systemui.statusbar.policy.DateView
+ android:id="@+id/date_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textColor="@color/clock_white"
+ android:textColor="?attr/bgProtectTextColor"
style="@style/widget_label"
android:letterSpacing="0.15"
android:gravity="center"
@@ -38,7 +39,7 @@
android:layout_height="wrap_content"
android:drawablePadding="6dp"
android:drawableStart="@drawable/ic_access_alarms_big"
- android:textColor="@color/clock_gray"
+ android:textColor="?attr/bgProtectSecondaryTextColor"
android:letterSpacing="0.15"
style="@style/widget_label"
android:layout_marginStart="6dp"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 51adc1e..44fae86 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -40,7 +40,7 @@
android:layout_gravity="center_horizontal"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
- android:textColor="@color/clock_white"
+ android:textColor="?attr/bgProtectTextColor"
android:singleLine="true"
style="@style/widget_big_thin"
android:format12Hour="@string/keyguard_widget_12_hours_format"
@@ -73,7 +73,7 @@
android:layout_marginTop="@dimen/date_owner_info_margin"
android:layout_centerHorizontal="true"
android:layout_below="@id/keyguard_status_area"
- android:textColor="@color/clock_gray"
+ android:textColor="?attr/bgProtectSecondaryTextColor"
android:textSize="@dimen/widget_label_font_size"
android:letterSpacing="0.05"
android:ellipsize="marquee"
diff --git a/packages/SystemUI/res-keyguard/values/attrs.xml b/packages/SystemUI/res-keyguard/values/attrs.xml
index 7cfe631..d3d60a1 100644
--- a/packages/SystemUI/res-keyguard/values/attrs.xml
+++ b/packages/SystemUI/res-keyguard/values/attrs.xml
@@ -35,9 +35,13 @@
<attr name="android:gravity" />
<attr name="dotSize" format="dimension" />
<attr name="charPadding" format="dimension" />
+ <attr name="android:textColor" format="color" />
</declare-styleable>
<declare-styleable name="CarrierText">
<attr name="allCaps" format="boolean" />
</declare-styleable>
+
+ <attr name="pinDividerColor" format="color" />
+ <attr name="pinDeleteColor" format="color" />
</resources>
diff --git a/packages/SystemUI/res-keyguard/values/colors.xml b/packages/SystemUI/res-keyguard/values/colors.xml
deleted file mode 100644
index 3998c5b..0000000
--- a/packages/SystemUI/res-keyguard/values/colors.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-
- <!-- Clock -->
- <color name="clock_white">#ffffffff</color>
- <color name="clock_gray">@*android:color/secondary_text_default_material_dark</color>
-</resources>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 53a559f..d7ff349 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -20,11 +20,11 @@
<resources>
<!-- Keyguard PIN pad styles -->
<style name="Keyguard.TextView" parent="@android:style/Widget.DeviceDefault.TextView">
- <item name="android:textColor">@*android:color/primary_device_default_light</item>
+ <item name="android:textColor">?attr/bgProtectSecondaryTextColor</item>
<item name="android:textSize">@dimen/kg_status_line_font_size</item>
</style>
<style name="Keyguard.TextView.EmergencyButton" parent="@android:style/DeviceDefault.ButtonBar">
- <item name="android:textColor">@*android:color/primary_device_default_light</item>
+ <item name="android:textColor">?attr/bgProtectSecondaryTextColor</item>
<item name="android:textSize">@dimen/kg_status_line_font_size</item>
<item name="android:background">@null</item>
</style>
@@ -34,13 +34,16 @@
<item name="android:background">@null</item>
<item name="android:textSize">36sp</item>
<item name="android:fontFamily">sans-serif-light</item>
- <item name="android:textColor">#ffffffff</item>
+ <item name="android:textColor">?attr/bgProtectTextColor</item>
<item name="android:paddingBottom">-16dp</item>
</style>
+ <style name="Keyguard.ImageButton.NumPadEnter" parent="@android:style/Widget.ImageButton">
+ <item name="android:tint">?attr/bgProtectTextColor</item>
+ </style>
<style name="Widget.TextView.NumPadKey.Klondike" parent="Widget.TextView.NumPadKey">
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">sans-serif</item>
- <item name="android:textColor">#80ffffff</item>
+ <item name="android:textColor">?attr/bgProtectSecondaryTextColor</item>
<item name="android:paddingBottom">0dp</item>
</style>
@@ -58,8 +61,9 @@
</style>
<style name="PasswordTheme" parent="@android:style/Theme.DeviceDefault">
- <item name="android:colorControlNormal">#80ffffff</item>
- <item name="android:colorControlActivated">#80ffffff</item>
+ <item name="android:textColor">?attr/bgProtectTextColor</item>
+ <item name="android:colorControlNormal">?attr/bgProtectTextColor</item>
+ <item name="android:colorControlActivated">?attr/bgProtectTextColor</item>
</style>
<style name="keyguard_presentation_theme" parent="@android:style/Theme.Material.NoActionBar.Fullscreen">
diff --git a/packages/SystemUI/res/color/background_protect_secondary.xml b/packages/SystemUI/res/color/background_protect_secondary.xml
new file mode 100644
index 0000000..26dc151
--- /dev/null
+++ b/packages/SystemUI/res/color/background_protect_secondary.xml
@@ -0,0 +1,20 @@
+<?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
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="?attr/bgProtectSecondaryTextColor" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/background_protected.xml b/packages/SystemUI/res/color/background_protected.xml
new file mode 100644
index 0000000..ab8ed87
--- /dev/null
+++ b/packages/SystemUI/res/color/background_protected.xml
@@ -0,0 +1,20 @@
+<?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
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="?attr/bgProtectTextColor" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/pin_delete_color.xml b/packages/SystemUI/res/color/pin_delete_color.xml
new file mode 100644
index 0000000..bb8b8e3
--- /dev/null
+++ b/packages/SystemUI/res/color/pin_delete_color.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:alpha="0.61" android:color="?attr/bgProtectTextColor" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/pin_divider_color.xml b/packages/SystemUI/res/color/pin_divider_color.xml
new file mode 100644
index 0000000..ca5f431
--- /dev/null
+++ b/packages/SystemUI/res/color/pin_divider_color.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2017 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:alpha="0.45" android:color="?attr/bgProtectSecondaryTextColor" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_access_alarms_small.xml b/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
index b94cc8e..f6e5ceb 100644
--- a/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
+++ b/packages/SystemUI/res/drawable/ic_access_alarms_small.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -17,10 +17,8 @@
android:width="16dp"
android:height="16dp"
android:viewportWidth="24.0"
- android:viewportHeight="24.0"
- android:tint="?android:attr/textColorTertiary">
-
+ android:viewportHeight="24.0">
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M22.0,5.7l-4.6,-3.9l-1.3,1.5l4.6,3.9L22.0,5.7zM7.9,3.4L6.6,1.9L2.0,5.7l1.3,1.5L7.9,3.4zM12.5,8.0L11.0,8.0l0.0,6.0l4.7,2.9l0.8,-1.2l-4.0,-2.4L12.5,8.0zM12.0,4.0c-5.0,0.0 -9.0,4.0 -9.0,9.0c0.0,5.0 4.0,9.0 9.0,9.0s9.0,-4.0 9.0,-9.0C21.0,8.0 17.0,4.0 12.0,4.0zM12.0,20.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.9 3.1,-7.0 7.0,-7.0c3.9,0.0 7.0,3.1 7.0,7.0C19.0,16.9 15.9,20.0 12.0,20.0z"/>
+ android:pathData="M21.35,6.49c-0.35,0.42 -0.98,0.47 -1.4,0.12l-3.07,-2.57a1,1 0,1 1,1.29 -1.53l3.07,2.57c0.42,0.35 0.47,0.98 0.11,1.41zM7.24,2.63a1,1 0,0 0,-1.41 -0.13L2.77,5.07A0.996,0.996 0,1 0,4.05 6.6l3.06,-2.57c0.43,-0.35 0.48,-0.98 0.13,-1.4zM11.75,8c-0.41,0 -0.75,0.34 -0.75,0.75v4.68c0,0.35 0.18,0.68 0.49,0.86l3.65,2.19c0.34,0.2 0.78,0.1 0.98,-0.24a0.71,0.71 0,0 0,-0.25 -0.99l-3.37,-2v-4.5c0,-0.41 -0.34,-0.75 -0.75,-0.75zM12,5.9c-3.91,0 -7.1,3.18 -7.1,7.1s3.19,7.1 7.1,7.1 7.1,-3.18 7.1,-7.1 -3.19,-7.1 -7.1,-7.1M12,4a9,9 0,1 1,-0.001 18.001A9,9 0,0 1,12 4z"
+ android:fillColor="#FFFFFFFF"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver.xml b/packages/SystemUI/res/drawable/ic_data_saver.xml
index 64bbff0..0f027ee 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -14,18 +14,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0"
- android:tint="?android:attr/colorControlNormal">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal">
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
+ android:pathData="M16,12c0,0.55 -0.45,1 -1,1h-2v2c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1v-2L9,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h2L11,9c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v2h2c0.55,0 1,0.45 1,1zM17.69,16.87a7.437,7.437 0,0 1,-5.93 2.63c-3.82,-0.12 -7.03,-3.25 -7.25,-7.07 -0.21,-3.84 2.48,-7.1 6.07,-7.79 0.24,-0.04 0.42,-0.24 0.42,-0.48L11,2.62c0,-0.3 -0.27,-0.55 -0.57,-0.5A10.02,10.02 0,0 0,2.09 13.4c0.59,4.4 4.16,7.94 8.56,8.52a9.99,9.99 0,0 0,9.14 -3.65,0.5 0.5,0 0,0 -0.15,-0.74l-1.32,-0.76a0.469,0.469 0,0 0,-0.63 0.1z"
+ android:fillColor="#FFFFFFFF"/>
<path
- android:fillColor="#54FFFFFF"
- android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M16.0,11.0l0.0,2.0 -3.0,0.0 0.0,3.0 -2.0,0.0 0.0,-3.0 -3.0,0.0 0.0,-2.0 3.0,0.0 0.0,-3.0 2.0,0.0 0.0,3.0z"/>
+ android:pathData="M13.41,4.64a0.493,0.493 0,0 1,-0.41 -0.48L13,2.62c0,-0.3 0.27,-0.55 0.57,-0.5C18.35,2.88 22,7.01 22,12c0,1.23 -0.23,2.41 -0.64,3.5 -0.11,0.28 -0.45,0.4 -0.72,0.24l-1.33,-0.77a0.484,0.484 0,0 1,-0.21 -0.59c0.25,-0.75 0.39,-1.55 0.39,-2.38 0.01,-3.65 -2.62,-6.69 -6.08,-7.36z"
+ android:fillColor="#54FFFFFF" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_data_saver_off.xml b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
index 3001ad9..29e6c91 100644
--- a/packages/SystemUI/res/drawable/ic_data_saver_off.xml
+++ b/packages/SystemUI/res/drawable/ic_data_saver_off.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -21,8 +21,5 @@
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M12.0,19.0c-3.9,0.0 -7.0,-3.1 -7.0,-7.0c0.0,-3.5 2.6,-6.4 6.0,-6.9L11.0,2.0C5.9,2.5 2.0,6.8 2.0,12.0c0.0,5.5 4.5,10.0 10.0,10.0c3.3,0.0 6.2,-1.6 8.1,-4.1l-2.6,-1.5C16.2,18.0 14.2,19.0 12.0,19.0z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13.0,2.0l0.0,3.0c3.4,0.5 6.0,3.4 6.0,6.9c0.0,0.9 -0.2,1.8 -0.5,2.5l2.6,1.5c0.6,-1.2 0.9,-2.6 0.9,-4.1C22.0,6.8 18.0,2.6 13.0,2.0z"/>
+ android:pathData="M18.32,16.75l1.32,0.76c0.26,0.15 0.34,0.51 0.15,0.74 -2.09,2.6 -5.44,4.14 -9.14,3.65 -4.4,-0.58 -7.96,-4.12 -8.56,-8.52C1.34,7.8 5.21,2.95 10.43,2.12c0.3,-0.05 0.57,0.2 0.57,0.5v1.53c0,0.24 -0.18,0.44 -0.41,0.49 -3.6,0.69 -6.29,3.95 -6.07,7.79 0.21,3.82 3.43,6.95 7.25,7.07 2.37,0.08 4.51,-0.96 5.93,-2.63a0.48,0.48 0,0 1,0.62 -0.12zM19.5,12c0,0.83 -0.14,1.63 -0.39,2.38 -0.08,0.23 0.01,0.47 0.21,0.59l1.33,0.77c0.26,0.15 0.61,0.04 0.72,-0.24 0.4,-1.09 0.63,-2.27 0.63,-3.5 0,-4.99 -3.65,-9.12 -8.43,-9.88 -0.3,-0.04 -0.57,0.2 -0.57,0.5v1.53c0,0.24 0.18,0.44 0.41,0.48 3.46,0.68 6.09,3.72 6.09,7.37z" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot.xml b/packages/SystemUI/res/drawable/ic_hotspot.xml
new file mode 100644
index 0000000..8450bf6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_hotspot.xml
@@ -0,0 +1,28 @@
+<?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="48dp"
+ android:height="48dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <group
+ android:translateY="-0.32">
+ <path
+ android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13a6,6 0,0 0,-6.75 -5.95c-2.62,0.32 -4.78,2.41 -5.18,5.02 -0.32,2.14 0.49,4.11 1.92,5.39 0.48,0.43 1.24,0.33 1.56,-0.23 0.24,-0.42 0.14,-0.94 -0.22,-1.26a3.99,3.99 0,0 1,-1.22 -3.94,3.954 3.954,0 0,1 2.9,-2.91A4.007,4.007 0,0 1,16 13c0,1.18 -0.51,2.23 -1.33,2.96 -0.36,0.33 -0.47,0.85 -0.23,1.27 0.31,0.54 1.04,0.69 1.5,0.28A5.97,5.97 0,0 0,18 13zM10.83,3.07c-4.62,0.52 -8.35,4.33 -8.78,8.96a9.966,9.966 0,0 0,4.02 9.01c0.48,0.35 1.16,0.2 1.46,-0.31 0.25,-0.43 0.14,-0.99 -0.26,-1.29 -2.28,-1.69 -3.65,-4.55 -3.16,-7.7 0.54,-3.5 3.46,-6.29 6.98,-6.68C15.91,4.51 20,8.28 20,13c0,2.65 -1.29,4.98 -3.27,6.44 -0.4,0.3 -0.51,0.85 -0.26,1.29 0.3,0.52 0.98,0.66 1.46,0.31A9.96,9.96 0,0 0,22 13c0,-5.91 -5.13,-10.62 -11.17,-9.93z"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_disable.xml b/packages/SystemUI/res/drawable/ic_hotspot_disable.xml
deleted file mode 100644
index 2570483..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_disable.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:alpha="1.0"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48"
- android:tint="?android:attr/colorControlNormal" >
- <group
- android:name="ic_hotspot"
- android:translateX="23.9778"
- android:translateY="24.26443" >
- <group
- android:name="ic_hotspot_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 6.97125244141,7.33258056641 6.97125244141,7.33258056641 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -6.77128601074,-6.82850646973 -6.77128601074,-6.82850646973 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 0.659332275391,0.664688110352 0.659332275391,0.664688110351 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 29.0108337402,34.4080963135 29.0108337402,34.4080963135 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 4.44044494629,2.24310302734 c 0.0,0.0 0.0875396728516,0.112457275391 0.0875396728516,0.112457275391 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="0"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="hotspot"
- android:translateX="23.481"
- android:translateY="18.71151" >
- <group
- android:name="circles"
- android:translateX="-0.23909"
- android:translateY="-0.10807" >
- <path
- android:name="path_3"
- android:pathData="M -0.0042724609375,-2.64895629883 c -2.20922851562,0.0 -4.0,1.791015625 -4.0,4.0 c 0.0,2.20922851562 1.79077148438,4.0 4.0,4.0 c 2.208984375,0.0 4.0,-1.79077148438 4.0,-4.0 c 0.0,-2.208984375 -1.791015625,-4.0 -4.0,-4.0 Z M 11.9957275391,1.35104370117 c 0.0,-6.626953125 -5.373046875,-12.0 -12.0,-12.0 c -6.62719726562,0.0 -12.0,5.373046875 -12.0,12.0 c 0.0,4.43603515625 2.41381835938,8.30004882812 5.99194335938,10.3771972656 c 0.0,0.0 2.01586914062,-3.48217773438 2.01586914062,-3.48217773438 c -2.38500976562,-1.38500976562 -4.0078125,-3.93798828125 -4.0078125,-6.89501953125 c 0.0,-4.41796875 3.58178710938,-8.0 8.0,-8.0 c 4.41796875,0.0 8.0,3.58203125 8.0,8.0 c 0.0,2.95703125 -1.623046875,5.51000976562 -4.00805664062,6.89501953125 c 0.0,0.0 2.01586914062,3.48217773438 2.01586914062,3.48217773438 c 3.578125,-2.0771484375 5.9921875,-5.94116210938 5.9921875,-10.3771972656 Z M -0.0042724609375,-18.6489562988 c -11.0451660156,0.0 -20.0,8.9541015625 -20.0,20.0 c 0.0,7.39306640625 4.02099609375,13.8330078125 9.98779296875,17.2951660156 c 0.0,0.0 2.00219726562,-3.458984375 2.00219726562,-3.458984375 c -4.77319335938,-2.77001953125 -7.98999023438,-7.92211914062 -7.98999023438,-13.8361816406 c 0.0,-8.8369140625 7.16381835938,-16.0 16.0,-16.0 c 8.83595275879,0.0 16.0000152588,7.1630859375 16.0000152588,16.0 c 0.0,5.9140625 -3.21704101562,11.0661621094 -7.990234375,13.8361816406 c 0.0,0.0 2.00219726562,3.458984375 2.00219726563,3.458984375 c 5.966796875,-3.46215820312 9.98803710937,-9.90209960938 9.98803710938,-17.2951660156 c 0.0,-11.0458984375 -8.955078125,-20.0 -20.0000152588,-20.0 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_hotspot_enable.xml b/packages/SystemUI/res/drawable/ic_hotspot_enable.xml
deleted file mode 100644
index 7a99630..0000000
--- a/packages/SystemUI/res/drawable/ic_hotspot_enable.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48" >
- <group
- android:name="ic_hotspot"
- android:translateX="23.97354"
- android:translateY="24.26306" >
- <group
- android:name="ic_hotspot_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -38.4077911377,30.8523712158 -38.4077911377,30.8523712158 c 0.0,0.0 43.1884765625,43.515335083 43.1884765625,43.515335083 c 0.0,0.0 -2.4169921875,2.57838439941 -2.4169921875,2.57838439941 c 0.0,0.0 -42.9885101318,-43.0112609863 -42.9885101318,-43.0112609863 c 0.0,0.0 -32.6199798584,25.1699066162 -32.6199798584,25.1699066162 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 27.6589050293,-22.6579437256 27.6589050293,-22.6579437256 c 0.0,0.0 -30.8645172119,-34.00390625 -30.8645172119,-34.00390625 c 0.0,0.0 2.70756530762,-1.99278259277 2.70756530762,-1.99278259277 c 0.0,0.0 1.53030395508,-0.876571655273 1.53030395508,-0.876571655274 c 0.0,0.0 2.85780334473,-3.12069702148 2.85780334473,-3.12069702148 c 0.0,0.0 13.0984039307,13.025604248 13.0984039307,13.025604248 c 0.0,0.0 -3.13299560547,2.82977294922 -3.13299560547,2.82977294922 c 0.0,0.0 16.571762085,22.0471801758 16.571762085,22.0471801758 c 0.0,0.0 42.8175811768,-34.3554534912 42.8175811768,-34.3554534912 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 4.44044494629,2.24310302734 c 0.0,0.0 35.4000396729,35.3999633789 35.4000396729,35.3999633789 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="1"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="hotspot"
- android:translateX="23.481"
- android:translateY="18.71151" >
- <group
- android:name="circles"
- android:translateX="-0.23909"
- android:translateY="-0.10807" >
- <path
- android:name="circle_3"
- android:pathData="M 0.0843505859375,-2.93901062012 c -2.30102539062,0.0 -4.16702270508,1.86602783203 -4.16702270508,4.16702270508 c 0.0,2.29898071289 1.86599731445,4.16598510742 4.16702270508,4.16598510742 c 2.29998779297,0.0 4.16598510742,-1.86700439453 4.16598510742,-4.16598510742 c 0.0,-2.30099487305 -1.86599731445,-4.16702270508 -4.16598510742,-4.16702270508 Z M 11.1185302734,5.83390808105 c 0.0,0.0 0.0009765625,0.00100708007812 0.0009765625,0.00100708007812 c 0.14501953125,-0.356994628906 0.27099609375,-0.725006103516 0.382995605469,-1.09799194336 c 0.0570068359375,-0.195007324219 0.101013183594,-0.394989013672 0.149017333984,-0.595001220703 c 0.0690002441406,-0.281005859375 0.126983642578,-0.563995361328 0.175994873047,-0.851989746094 c 0.0270080566406,-0.169006347656 0.0559997558594,-0.337005615234 0.0759887695313,-0.509002685547 c 0.0580139160156,-0.468017578125 0.0970153808594,-0.942993164062 0.0970153808593,-1.4280090332 c 0.0,0.0 0.0,-0.00100708007812 0.0,-0.00100708007812 c 0.0,-5.03900146484 -3.11099243164,-9.3450012207 -7.5119934082,-11.1229858398 c -0.00601196289062,-0.00299072265625 -0.0130004882812,-0.0050048828125 -0.0190124511719,-0.00701904296875 c -0.686004638672,-0.275970458984 -1.39999389648,-0.492980957031 -2.14099121094,-0.638977050781 c -0.072998046875,-0.0150146484375 -0.149017333984,-0.02099609375 -0.222991943359,-0.0339965820313 c -0.302001953125,-0.0540161132812 -0.605010986328,-0.106018066406 -0.916015625,-0.136016845703 c -0.389984130859,-0.0390014648438 -0.786987304688,-0.0599975585938 -1.18899536133,-0.0599975585937 c -0.402008056641,0.0 -0.799011230469,0.02099609375 -1.19000244141,0.0599975585937 c -0.304992675781,0.0299987792969 -0.602996826172,0.0809936523438 -0.901000976563,0.132995605469 c -0.0790100097656,0.0150146484375 -0.160003662109,0.02099609375 -0.238006591797,0.0370178222656 c -0.368988037109,0.0719909667969 -0.730987548828,0.164001464844 -1.08700561523,0.269989013672 c -0.00299072265625,0.00100708007812 -0.0059814453125,0.00201416015625 -0.00900268554687,0.0020141601562 c -0.351989746094,0.10498046875 -0.694000244141,0.226989746094 -1.0309753418,0.361999511719 c -0.0110168457031,0.00399780273438 -0.0220031738281,0.00698852539062 -0.0320129394531,0.0119934082031 c -4.40200805664,1.77798461914 -7.51098632812,6.083984375 -7.5119934082,11.1229858398 c 0.0,0.00799560546875 0.00198364257812,0.0160217285156 0.0019836425781,0.0240173339844 c 0.00100708007812,0.475006103516 0.0380249023438,0.940002441406 0.0950012207032,1.39898681641 c 0.02001953125,0.175994873047 0.0490112304688,0.348999023438 0.0780029296875,0.523010253906 c 0.0469970703125,0.281982421875 0.105010986328,0.557983398438 0.171997070312,0.833984375 c 0.0480041503906,0.204010009766 0.093017578125,0.410003662109 0.152008056641,0.610015869141 c 0.110992431641,0.372009277344 0.238006591797,0.736999511719 0.382019042969,1.09298706055 c 0.0,0.0 0.0009765625,0.0 0.0009765625,0.0 c 1.00701904297,2.48400878906 2.81301879883,4.56100463867 5.11001586914,5.89501953125 c 0.0,0.0 2.01599121094,-3.48300170898 2.01599121094,-3.48300170898 c -2.03900146484,-1.18402099609 -3.5119934082,-3.22500610352 -3.89898681641,-5.63900756836 c 0.0,0.0 0.0009765625,-0.00100708007812 0.0009765625,-0.00100708007812 c -0.0220031738281,-0.130981445312 -0.0369873046875,-0.265991210938 -0.052978515625,-0.399993896484 c -0.0290222167969,-0.274993896484 -0.0570068359375,-0.552001953125 -0.0570068359375,-0.834991455078 c 0.0,0.0 0.0,-0.0190124511719 0.0,-0.0190124511719 c 0.0,-3.98999023438 2.92498779297,-7.28900146484 6.74398803711,-7.89199829102 c 0.0,0.0 0.0180053710938,0.0169982910156 0.0180053710938,0.0169982910156 c 0.404998779297,-0.0639953613281 0.81298828125,-0.125 1.23599243164,-0.125 c 0.0,0.0 0.00201416015625,0.0 0.00201416015624,0.0 c 0.0,0.0 0.00299072265625,0.0 0.00299072265626,0.0 c 0.423004150391,0.0 0.830017089844,0.0610046386719 1.23501586914,0.125 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c 3.81997680664,0.60400390625 6.74499511719,3.90301513672 6.74499511719,7.89199829102 c 0.0,0.292999267578 -0.0280151367188,0.578002929688 -0.0589904785156,0.861999511719 c -0.0150146484375,0.132019042969 -0.0290222167969,0.264007568359 -0.051025390625,0.393005371094 c -0.385986328125,2.41500854492 -1.85897827148,4.45599365234 -3.89797973633,5.64001464844 c 0.0,0.0 2.01599121094,3.48300170898 2.01599121094,3.48300170898 c 2.29699707031,-1.33401489258 4.10299682617,-3.41101074219 5.11001586914,-5.89602661133 Z M 19.9300231934,2.95698547363 c 0.0059814453125,-0.0659790039062 0.0159912109375,-0.130981445312 0.02099609375,-0.196990966797 c 0.031982421875,-0.462005615234 0.0479736328125,-0.928009033203 0.0489807128906,-1.39700317383 c 0,0.0 0,-0.00997924804688 0,-0.00997924804687 c 0,0.0 0,-0.00100708007812 0,-0.00100708007813 c 0,-7.22500610352 -3.84399414062,-13.5360107422 -9.58599853516,-17.0500183105 c -1.06500244141,-0.652984619141 -2.19299316406,-1.20599365234 -3.37799072266,-1.65197753906 c -0.157989501953,-0.0599975585938 -0.317016601562,-0.118011474609 -0.476989746094,-0.174011230469 c -0.317016601562,-0.110992431641 -0.634002685547,-0.218994140625 -0.9580078125,-0.31298828125 c -0.470001220703,-0.139007568359 -0.944000244141,-0.264007568359 -1.4280090332,-0.368011474609 c -0.186004638672,-0.0390014648438 -0.376983642578,-0.0669860839844 -0.565002441406,-0.101013183594 c -0.414001464844,-0.0759887695312 -0.832000732422,-0.140991210938 -1.25500488281,-0.190979003906 c -0.184997558594,-0.0220031738281 -0.369995117188,-0.0429992675781 -0.556976318359,-0.0599975585937 c -0.592010498047,-0.0530090332031 -1.18801879883,-0.0899963378906 -1.79602050781,-0.0899963378907 c -0.605987548828,0.0 -1.20300292969,0.0369873046875 -1.79598999023,0.0899963378907 c -0.186004638672,0.0169982910156 -0.371002197266,0.0379943847656 -0.555999755859,0.0599975585937 c -0.423004150391,0.0499877929688 -0.842010498047,0.114990234375 -1.25601196289,0.190979003906 c -0.18798828125,0.0350036621094 -0.377990722656,0.06201171875 -0.563995361328,0.101013183594 c -0.483001708984,0.10400390625 -0.959991455078,0.22900390625 -1.42999267578,0.368011474609 c -0.321990966797,0.093994140625 -0.638000488281,0.201995849609 -0.953002929688,0.311981201172 c -0.162994384766,0.0570068359375 -0.324005126953,0.115997314453 -0.484985351562,0.177001953125 c -1.18099975586,0.445007324219 -2.30599975586,0.997009277344 -3.36801147461,1.64700317383 c -0.00201416015625,0.00100708007812 -0.00399780273438,0.00201416015625 -0.0060119628907,0.0029907226562 c -5.74099731445,3.51400756836 -9.58499145508,9.82501220703 -9.58599853516,17.0500183105 c 0,0.0 0,0.00100708007812 0,0.00100708007813 c 0,0.0059814453125 0.00100708007812,0.0130004882812 0.0010070800781,0.0199890136719 c 0.0,0.466003417969 0.0169982910156,0.928009033203 0.0490112304688,1.38598632812 c 0.0050048828125,0.0690002441406 0.0159912109375,0.136016845703 0.02099609375,0.206024169922 c 0.031982421875,0.401000976562 0.0719909667969,0.799987792969 0.127990722656,1.19400024414 c 0.00201416015625,0.0189819335938 0.00701904296875,0.0369873046875 0.010009765625,0.0569763183594 c 0.888000488281,6.17202758789 4.59799194336,11.4250183105 9.7799987793,14.4309997559 c 0.0,0.0 2.00198364258,-3.458984375 2.00198364258,-3.458984375 c -2.58599853516,-1.5 -4.708984375,-3.70401000977 -6.11697387695,-6.34399414063 c 0.0,0.0 0.0169982910156,-0.0180053710938 0.0169982910156,-0.0180053710938 c -0.890014648438,-1.67098999023 -1.50601196289,-3.5110168457 -1.76000976562,-5.46499633789 c -0.00698852539062,-0.0500183105469 -0.010009765625,-0.102020263672 -0.0159912109375,-0.152008056641 c -0.0330200195312,-0.273010253906 -0.0610046386719,-0.545989990234 -0.0800170898437,-0.821990966797 c -0.0220031738281,-0.343017578125 -0.0350036621094,-0.68701171875 -0.0350036621094,-1.03500366211 c 0,-6.53701782227 3.92599487305,-12.1480102539 9.54299926758,-14.6310119629 c 0.157012939453,-0.0700073242188 0.313995361328,-0.135986328125 0.472015380859,-0.199981689453 c 0.373992919922,-0.151000976562 0.751983642578,-0.294006347656 1.13900756836,-0.417022705078 c 0.108978271484,-0.0350036621094 0.221984863281,-0.0619812011719 0.332000732422,-0.0950012207031 c 0.349975585938,-0.102996826172 0.705993652344,-0.194976806641 1.06597900391,-0.273986816406 c 0.114013671875,-0.0249938964844 0.227996826172,-0.052001953125 0.342010498047,-0.0750122070313 c 0.440002441406,-0.0869750976562 0.885986328125,-0.154998779297 1.33700561523,-0.203979492188 c 0.10400390625,-0.0120239257812 0.209991455078,-0.02001953125 0.315002441406,-0.0299987792969 c 0.47998046875,-0.0429992675781 0.963989257812,-0.072998046875 1.45397949219,-0.072998046875 c 0.492004394531,0.0 0.975006103516,0.0299987792969 1.45401000977,0.072998046875 c 0.105987548828,0.00997924804688 0.212005615234,0.0179748535156 0.316986083984,0.0299987792969 c 0.450012207031,0.0489807128906 0.89501953125,0.117004394531 1.33502197266,0.203002929688 c 0.115997314453,0.0239868164062 0.22998046875,0.0509948730469 0.345001220703,0.0769958496094 c 0.358001708984,0.0780029296875 0.710998535156,0.169982910156 1.06097412109,0.272003173828 c 0.111022949219,0.0329895019531 0.226013183594,0.0609741210938 0.336029052734,0.0969848632813 c 0.385986328125,0.123016357422 0.761993408203,0.265014648438 1.13497924805,0.415008544922 c 0.160003662109,0.0650024414062 0.319000244141,0.131988525391 0.477020263672,0.201995849609 c 5.61599731445,2.48400878906 9.53997802734,8.09399414062 9.53997802734,14.6310119629 c 0,0.346984863281 -0.0130004882812,0.690979003906 -0.0350036621094,1.03399658203 c -0.0179748535156,0.274993896484 -0.0469970703125,0.548004150391 -0.0789794921875,0.819000244141 c -0.00601196289062,0.052001953125 -0.010009765625,0.10498046875 -0.0160217285156,0.154998779297 c -0.252990722656,1.95498657227 -0.871002197266,3.79400634766 -1.75997924805,5.46499633789 c 0.0,0.0 0.0169982910156,0.0180053710938 0.0169982910156,0.0180053710938 c -1.40802001953,2.63998413086 -3.53100585938,4.84399414062 -6.11700439453,6.34399414063 c 0.0,0.0 2.00198364258,3.458984375 2.00198364258,3.458984375 c 5.18402099609,-3.00698852539 8.89501953125,-8.26300048828 9.78100585938,-14.4379882813 c 0.00201416015625,-0.0169982910156 0.00601196289062,-0.0320129394531 0.0079956054688,-0.0490112304688 c 0.0570068359375,-0.39697265625 0.0970153808594,-0.798980712891 0.129028320312,-1.20300292969 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors.xml b/packages/SystemUI/res/drawable/ic_invert_colors.xml
new file mode 100644
index 0000000..f7a86a4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_invert_colors.xml
@@ -0,0 +1,28 @@
+<?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="48dp"
+ android:height="48dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <group
+ android:translateX="-0.61">
+ <path
+ android:pathData="M17.44,7.71L12.7,2.97a0.996,0.996 0,0 0,-1.41 0L6.56,7.71c-3,3 -3.4,7.89 -0.62,11.1 1.6,1.85 3.83,2.77 6.06,2.77s4.46,-0.92 6.06,-2.77c2.78,-3.21 2.38,-8.1 -0.62,-11.1zM12,19.59c-1.6,0 -3.11,-0.62 -4.24,-1.76C6.62,16.69 6,15.19 6,13.59s0.62,-3.11 1.76,-4.24L12,5.1v14.49z"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
deleted file mode 100644
index 49ee48b..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_disable.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:alpha="1.0"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48"
- android:tint="?android:attr/colorControlNormal" >
- <group
- android:name="icon"
- android:translateX="21.9995"
- android:translateY="25.73401" >
- <group
- android:name="icon_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="0"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="ink_drop"
- android:translateY="-6.8" >
- <path
- android:name="outer_drop"
- android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml b/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
deleted file mode 100644
index 169cc71..0000000
--- a/packages/SystemUI/res/drawable/ic_invert_colors_enable.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48"
- android:tint="?android:attr/colorControlNormal" >
- <group
- android:name="icon"
- android:translateX="21.9995"
- android:translateY="25.73401" >
- <group
- android:name="icon_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="1"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="ink_drop"
- android:translateY="-6.8" >
- <path
- android:name="outer_drop"
- android:pathData="M 35.3000030518,15.8999938965 c 0.0,0.0 -11.3000030518,-11.3999938965 -11.3000030518,-11.3999938965 c 0,0.0 -11.3000030518,11.3999938965 -11.3000030518,11.3999938965 c -6.19999694824,6.20001220703 -6.19999694824,16.4000091553 0.0,22.6000061035 c 3.10000610352,3.10000610352 7.19999694824,4.69999694824 11.3000030518,4.69999694824 c 4.10000610352,0.0 8.19999694824,-1.59999084473 11.3000030518,-4.69999694824 c 6.30000305176,-6.30000305176 6.30000305176,-16.3999938965 0.0,-22.6000061035 Z M 24,39.1999969482 c 0,0.0 0,0.0 0,0.0 c -3.19999694824,0.0 -6.19999694824,-1.19999694824 -8.5,-3.5 c -2.30000305176,-2.29998779297 -3.5,-5.30000305176 -3.5,-8.5 c 0,-3.19999694824 1.19999694824,-6.19999694824 3.5,-8.5 c 0.0,0.0 8.5,-8.5 8.5,-8.5 c 0,0.0 0,29.0 0,29.0 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_mode_edit.xml b/packages/SystemUI/res/drawable/ic_mode_edit.xml
index f32da59..2ad3119 100644
--- a/packages/SystemUI/res/drawable/ic_mode_edit.xml
+++ b/packages/SystemUI/res/drawable/ic_mode_edit.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -21,5 +21,5 @@
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFF"
- android:pathData="M3.0,17.25L3.0,21.0l3.75,0.0L17.81,9.94l-3.75,-3.75L3.0,17.25zM20.71,7.04c0.39,-0.3 0.39,-1.02 0.0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0.0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
+ android:pathData="M3,18.08v2.42c0,0.28 0.22,0.5 0.5,0.5h2.42c0.53,0 1.04,-0.21 1.41,-0.59L17.81,9.94l-3.75,-3.75L3.59,16.66c-0.38,0.38 -0.59,0.89 -0.59,1.42zM20.71,7.04a0.996,0.996 0,0 0,0 -1.41l-2.34,-2.34a0.996,0.996 0,0 0,-1.41 0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
index 8a3e975..3eb81f8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connected.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,13 +14,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0"
- android:tint="?android:attr/colorControlNormal">
-
+ android:width="64dp"
+ android:height="64dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal" >
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M14.0,24.0l-4.0,-4.0l-4.0,4.0l4.0,4.0L14.0,24.0zM35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6zM38.0,20.0l-4.0,4.0l4.0,4.0l4.0,-4.0L38.0,20.0z"/>
+ android:pathData="M13.51,12l3.75,-3.74c0.41,-0.41 0.41,-1.07 0,-1.48l-4.47,-4.47 -0.03,-0.03a1.046,1.046 0,0 0,-1.76 0.76v6.44L6.95,5.43c-0.41,-0.41 -1.06,-0.41 -1.47,0s-0.41,1.06 0,1.47l5.09,5.1 -5.09,5.09c-0.41,0.41 -0.41,1.06 0,1.47s1.06,0.41 1.47,0L11,14.51v6.45a1.04,1.04 0,0 0,1.75 0.76l0.05,-0.05 4.46,-4.46c0.41,-0.41 0.41,-1.07 0,-1.48L13.51,12zM12.99,9.67v-4.3l2.15,2.15 -2.15,2.15zM12.99,18.62v-4.3l2.15,2.15 -2.15,2.15zM6.06,13.06c-0.59,0.59 -1.54,0.59 -2.12,0a1.49,1.49 0,0 1,0 -2.12,1.49 1.49,0 0,1 2.12,0c0.59,0.59 0.59,1.53 0,2.12zM20.06,10.94c0.59,0.59 0.59,1.54 0,2.12 -0.59,0.59 -1.54,0.59 -2.12,0a1.49,1.49 0,0 1,0 -2.12,1.49 1.49,0 0,1 2.12,0z"
+ android:fillColor="#FFFFFFFF" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
index 1dadc05..fbd92de 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,13 +14,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0"
- android:tint="?android:attr/colorControlNormal">
-
+ android:width="64dp"
+ android:height="64dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal" >
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M28.5,24.0l4.6,4.6c0.6,-1.4 0.9,-3.0 0.9,-4.7c0.0,-1.6 -0.3,-3.2 -0.9,-4.6L28.5,24.0zM39.1,13.4L36.5,16.0c1.3,2.4 2.0,5.1 2.0,8.0s-0.7,5.6 -2.0,8.0l2.4,2.4c1.9,-3.1 3.1,-6.7 3.1,-10.6C42.0,20.0 40.9,16.5 39.1,13.4zM31.4,15.4L20.0,4.0l-2.0,0.0l0.0,15.2L8.8,10.0L6.0,12.8L17.2,24.0L6.0,35.2L8.8,38.0l9.2,-9.2L18.0,44.0l2.0,0.0l11.4,-11.4L22.8,24.0L31.4,15.4zM22.0,11.7l3.8,3.8L22.0,19.2L22.0,11.7zM25.8,32.6L22.0,36.3l0.0,-7.5L25.8,32.6z"/>
+ android:pathData="M14.95,11.3l1.62,-1.61C16.84,10.41 17,11.18 17,12s-0.16,1.61 -0.44,2.33l-1.61,-1.61C14.56,12.33 14.56,11.69 14.95,11.3zM18.69,7.54c-0.26,0.26 -0.32,0.65 -0.17,0.98c0.47,1.07 0.72,2.24 0.72,3.47c0,1.24 -0.26,2.43 -0.73,3.49c-0.14,0.32 -0.09,0.69 0.16,0.94c0.4,0.4 1.09,0.29 1.34,-0.23c0.63,-1.3 0.98,-2.76 0.98,-4.3c-0.01,-1.46 -0.33,-2.86 -0.91,-4.12C19.84,7.23 19.12,7.11 18.69,7.54zM15.26,15.74c0.41,0.41 0.41,1.07 0,1.48l-4.51,4.51C10.57,21.89 10.32,22 10.04,22C9.47,22 9,21.53 9,20.96v-6.45l-4.05,4.05c-0.41,0.41 -1.06,0.41 -1.47,0s-0.41,-1.06 0,-1.47L8.57,12L3.48,6.9c-0.41,-0.41 -0.41,-1.06 0,-1.47s1.06,-0.41 1.47,0L9,9.49V3.04C9,2.47 9.47,2 10.04,2c0.28,0 0.53,0.11 0.72,0.29l4.5,4.5c0.41,0.41 0.41,1.07 0,1.48L11.51,12L15.26,15.74zM13.14,7.53l-2.15,-2.15v4.3C10.99,9.68 13.14,7.53 13.14,7.53zM13.14,16.47l-2.15,-2.15v4.3C10.99,18.62 13.14,16.47 13.14,16.47z"
+ android:fillColor="#FFFFFFFF" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
index 33a4047..e6d6f2c 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_detail_empty.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -16,12 +16,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="56dp"
android:height="56dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
android:alpha="0.14"
android:tint="?android:attr/colorForeground">
<path
android:fillColor="#FFFFFF"
- android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+ android:pathData="M13.5,12l3.8,-3.7c0.4,-0.4 0.4,-1.1 0,-1.5l-4.5,-4.5c-0.4,-0.4 -1.1,-0.4 -1.5,0.1C11.1,2.5 11,2.8 11,3v6.4L6.9,5.4C6.5,5 5.9,5 5.5,5.4s-0.4,1.1 0,1.5l5.1,5.1l-5.1,5.1c-0.4,0.4 -0.4,1.1 0,1.5s1.1,0.4 1.5,0l4.1,-4V21c0,0.6 0.5,1 1,1c0.3,0 0.5,-0.1 0.7,-0.3l0.1,0l4.5,-4.5c0.4,-0.4 0.4,-1.1 0,-1.5L13.5,12zM13,9.7V5.4l2.1,2.2L13,9.7zM13,18.6v-4.3l2.1,2.2L13,18.6z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml
deleted file mode 100644
index 3148a2c..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_off.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-Copyright (C) 2014 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="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0"
- android:tint="?android:attr/colorControlNormal">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M26.0,11.8l3.8,3.8l-3.2,3.2l2.8,2.8l6.0,-6.0L24.0,4.2l-2.0,0.0l0.0,10.1l4.0,4.0L26.0,11.8zM10.8,8.2L8.0,11.0l13.2,13.2L10.0,35.3l2.8,2.8L22.0,29.0l0.0,15.2l2.0,0.0l8.6,-8.6l4.6,4.6l2.8,-2.8L10.8,8.2zM26.0,36.5L26.0,29.0l3.8,3.8L26.0,36.5z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
index 2e9e741..8cc6caa 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_on.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,13 +14,12 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0"
- android:tint="?android:attr/colorControlNormal">
-
+ android:width="64dp"
+ android:height="64dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M35.4,15.4L24.0,4.0l-2.0,0.0l0.0,15.2L12.8,10.0L10.0,12.8L21.2,24.0L10.0,35.2l2.8,2.8l9.2,-9.2L22.0,44.0l2.0,0.0l11.4,-11.4L26.8,24.0L35.4,15.4zM26.0,11.7l3.8,3.8L26.0,19.2L26.0,11.7zM29.8,32.6L26.0,36.3l0.0,-7.5L29.8,32.6z"/>
+ android:pathData="M13.5,12l3.8,-3.7c0.4,-0.4 0.4,-1.1 0,-1.5l-4.5,-4.5c-0.4,-0.4 -1.1,-0.4 -1.5,0.1C11.1,2.5 11,2.8 11,3v6.4L6.9,5.4C6.5,5 5.9,5 5.5,5.4s-0.4,1.1 0,1.5l5.1,5.1l-5.1,5.1c-0.4,0.4 -0.4,1.1 0,1.5s1.1,0.4 1.5,0l4.1,-4V21c0,0.6 0.5,1 1,1c0.3,0 0.5,-0.1 0.7,-0.3l0.1,0l4.5,-4.5c0.4,-0.4 0.4,-1.1 0,-1.5L13.5,12zM13,9.7V5.4l2.1,2.2L13,9.7zM13,18.6v-4.3l2.1,2.2L13,18.6z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
index b7fe5ab..aaebc77 100644
--- a/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_brightness_auto_off.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2014 The Android Open Source Project
+ 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.
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
index fc831f4..ffde286 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_detail_empty.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -23,5 +23,5 @@
<path
android:fillColor="#FFFFFF"
- android:pathData="M42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0z"/>
+ android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml b/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
index 06a0886..9e57577 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_off.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,12 +14,11 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
+ android:width="64dp"
+ android:height="64dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0z"/>
+ android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z"
+ android:fillColor="#FFFFFFFF" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
index 794eb9e..3dda87c 100644
--- a/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_cast_on.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -16,10 +16,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M2.0,36.0l0.0,6.0l6.0,0.0C8.0,38.7 5.3,36.0 2.0,36.0zM2.0,28.0l0.0,4.0c5.5,0.0 10.0,4.5 10.0,10.0l4.0,0.0C16.0,34.3 9.7,28.0 2.0,28.0zM38.0,14.0L10.0,14.0l0.0,3.3c7.9,2.6 14.2,8.8 16.7,16.7L38.0,34.0L38.0,14.0zM2.0,20.0l0.0,4.0c9.9,0.0 18.0,8.1 18.0,18.0l4.0,0.0C24.0,29.8 14.1,20.0 2.0,20.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,6.0l4.0,0.0l0.0,-6.0l36.0,0.0l0.0,28.0L28.0,38.0l0.0,4.0l14.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0z"/>
+ android:pathData="M1,18v2c0,0.55 0.45,1 1,1h2c0,-1.66 -1.34,-3 -3,-3zM0.97,15.06c-0.01,0.51 0.35,0.93 0.85,1.02 2.08,0.36 3.74,2 4.1,4.08 0.09,0.48 0.5,0.84 0.99,0.84 0.61,0 1.09,-0.54 1,-1.14a6.996,6.996 0,0 0,-5.8 -5.78c-0.59,-0.09 -1.12,0.38 -1.14,0.98zM19,7L5,7v1.63c3.96,1.28 7.09,4.41 8.37,8.37L19,17L19,7zM0.97,11.03c-0.01,0.52 0.37,0.96 0.88,1.01 4.26,0.43 7.68,3.82 8.1,8.08 0.05,0.5 0.48,0.88 0.99,0.88 0.59,0 1.06,-0.51 1,-1.1 -0.52,-5.21 -4.66,-9.34 -9.87,-9.85 -0.57,-0.05 -1.08,0.4 -1.1,0.98zM21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2z" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml
new file mode 100644
index 0000000..d71018b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_detail_empty.xml
@@ -0,0 +1,26 @@
+<!--
+ 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="56dp"
+ android:height="56dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:alpha="0.14"
+ android:tint="?android:attr/colorForeground">
+ <path
+ android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"
+ android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml
deleted file mode 100644
index 9168dbc..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_off.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
-Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="64dp"
- android:viewportHeight="24.0"
- android:viewportWidth="24.0"
- android:width="64dp" >
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13.8,11.1L17.0,11.1l0.0,2.0l-1.2,0.0l4.5,4.5c1.1,-1.6 1.7,-3.5 1.7,-5.5c0.0,-5.5 -4.5,-10.0 -10.0,-10.0c-2.0,0.0 -3.9,0.6 -5.5,1.7L13.8,11.1z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13.0,13.1L7.0,13.1l0.0,-2.0l4.0,0.0L4.9,5.0C3.1,6.8 2.0,9.3 2.0,12.1c0.0,5.5 4.5,10.0 10.0,10.0c2.8,0.0 5.3,-1.1 7.1,-2.9L13.0,13.1z" />
-
- <group
- android:pivotX="12.0"
- android:pivotY="12.0"
- android:rotation="45.0"
- android:translateX="0.5"
- android:translateY="0.5" >
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M-2.8,11.8l28.3,0.0l0.0,2.0l-28.3,0.0z" />
- </group>
-
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
index f4c20a9..233b9b9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_on.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ 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.
@@ -16,9 +16,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M24.0,4.0C12.95,4.0 4.0,12.95 4.0,24.0s8.95,20.0 20.0,20.0 20.0,-8.95 20.0,-20.0S35.05,4.0 24.0,4.0zm10.0,22.0L14.0,26.0l0.0,-4.0l20.0,0.0l0.0,4.0z"/>
+ android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM16,13L8,13c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1z"
+ android:fillColor="#FFFFFFFF"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml b/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
index fb26c09..5012aa4 100644
--- a/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_dnd_on_total_silence.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2015 The Android Open Source Project
+ 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.
@@ -18,12 +18,7 @@
android:height="64dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
-
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0s10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,20.5c-4.7,0.0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12.0,3.5s8.5,3.8 8.5,8.5S16.7,20.5 12.0,20.5z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M12.0,6.0c-3.3,0.0 -6.0,2.7 -6.0,6.0c0.0,3.3 2.7,6.0 6.0,6.0s6.0,-2.7 6.0,-6.0C18.0,8.7 15.4,6.0 12.0,6.0zM15.0,13.0L9.0,13.0l0.0,-2.0l6.0,0.0L15.0,13.0z"/>
-
+ android:pathData="M12,2C6.5,2 2,6.5 2,12s4.5,10 10,10 10,-4.5 10,-10S17.5,2 12,2zM12,20.5c-4.7,0 -8.5,-3.8 -8.5,-8.5S7.3,3.5 12,3.5s8.5,3.8 8.5,8.5 -3.8,8.5 -8.5,8.5zM12,6c-3.3,0 -6,2.7 -6,6s2.7,6 6,6 6,-2.7 6,-6 -2.6,-6 -6,-6zM14,13h-4c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1h4c0.55,0 1,0.45 1,1s-0.45,1 -1,1z" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml
deleted file mode 100644
index aaca663..0000000
--- a/packages/SystemUI/res/drawable/ic_qs_night_display_off.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
- <path
- android:fillColor="#FFF"
- android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
-
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml b/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
index aaca663..8801f5d 100644
--- a/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_night_display_on.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -16,11 +16,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
-
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
<path
- android:fillColor="#FFF"
- android:pathData="M6,12c0,5.5,4.5,10,10,10c1,0,2-0.2,3-0.5c-4.1-1.3-7-5.1-7-9.5s2.9-8.3,7-9.5C18.1,2.2,17.1,2,16,2C10.5,2,6,6.5,6,12z" />
-
-</vector>
+ android:pathData="M13,12c0,-3.57 2.2,-6.62 5.31,-7.87 0.89,-0.36 0.75,-1.69 -0.19,-1.9 -1.1,-0.24 -2.27,-0.3 -3.48,-0.14 -4.51,0.6 -8.12,4.31 -8.59,8.83C5.43,16.93 10.12,22 16,22c0.73,0 1.43,-0.08 2.12,-0.23 0.95,-0.21 1.1,-1.53 0.2,-1.9A8.471,8.471 0,0 1,13 12z"
+ android:fillColor="#FFF"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml
index e6f9292..7cbc26f 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_0.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -14,15 +14,19 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
- android:fillAlpha="0.3"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
- android:fillColor="#FFFFFF"/>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="25.50"
+ android:viewportHeight="25.50">
+ <group
+ android:translateX="0.77"
+ android:translateY="0.23" >
+ <path
+ android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+ android:fillAlpha="0.3"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38 0.38,1 0,1.38v0c-0.38,0.38 -1,0.39 -1.38,0l-1.83,-1.83l-1.83,1.83c-0.38,0.38 -1,0.38 -1.38,0l-0.01,-0.01c-0.38,-0.38 -0.38,-1 0,-1.38l1.83,-1.83l-1.82,-1.82c-0.38,-0.38 -0.38,-1 0,-1.38l0.01,-0.01c0.38,-0.38 1,-0.38 1.38,0l1.82,1.82l1.82,-1.82c0.38,-0.38 1,-0.38 1.38,0l0,0C23.09,14.67 23.09,15.29 22.71,15.67z"
+ android:fillColor="#FFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml
index d423ccb..675dfc9 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_1.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -14,18 +14,19 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:pathData="M13.8,13.2c-0.1,0.0 -0.3,-0.1 -0.4,-0.1c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,0.0 -0.6,-0.1 -0.9,-0.1c0.0,0.0 0.0,0.0 -0.1,0.0c0.0,0.0 0.0,0.0 0.0,0.0s0.0,0.0 0.0,0.0c0.0,0.0 0.0,0.0 -0.1,0.0c-0.3,0.0 -0.6,0.0 -0.9,0.1c-0.1,0.0 -0.3,0.0 -0.4,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.2,0.0 -0.3,0.1 -0.5,0.1c-0.1,0.0 -0.1,0.0 -0.2,0.1c-1.6,0.5 -2.7,1.3 -2.8,1.5l5.3,6.6l0.0,0.0l0.0,0.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.700002,13.2z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
- android:fillAlpha="0.3"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.799999,-1.800001z"
- android:fillColor="#FFFFFF"/>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="25.50"
+ android:viewportHeight="25.50">
+ <group
+ android:translateX="0.77"
+ android:translateY="0.23" >
+ <path
+ android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+ android:fillAlpha="0.3"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0l-5.1,-6.35C7.65,13.85 9.72,13 12,13c0.69,0 1.36,0.08 2,0.23V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+ android:fillColor="#FFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml
index 1982130..c9a7eb8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_2.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -14,18 +14,19 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:pathData="M13.8,12.2l4.9,0.0c-1.0,-0.7 -3.4,-2.2 -6.7,-2.2c-4.1,0.0 -6.9,2.2 -7.2,2.5l7.2,9.0l0.0,0.0l0.0,0.0l1.8,-2.2L13.800001,12.2z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
- android:fillAlpha="0.3"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.800001,1.9 -1.800001,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
- android:fillColor="#FFFFFF"/>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="25.50"
+ android:viewportHeight="25.50">
+ <group
+ android:translateX="0.77"
+ android:translateY="0.23" >
+ <path
+ android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+ android:fillAlpha="0.3"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0l-6.98,-8.7C6.28,11.1 9.01,10 12,10c2.45,0 4.72,0.74 6.62,2H14V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+ android:fillColor="#FFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml
index b350111..a6facae 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_3.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -14,18 +14,19 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:pathData="M13.8,12.2l5.7,0.0l1.0,-1.2C20.0,10.6 16.8,8.0 12.0,8.0s-8.0,2.6 -8.5,3.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
- android:fillAlpha="0.3"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
- android:fillColor="#FFFFFF"/>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="25.50"
+ android:viewportHeight="25.50">
+ <group
+ android:translateX="0.77"
+ android:translateY="0.23" >
+ <path
+ android:pathData="M14,12h6.54l3.12,-3.89c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+ android:fillAlpha="0.3"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M14,20.13l-1.18,1.47c-0.43,0.53 -1.23,0.53 -1.66,0L2.93,11.35C5.37,9.26 8.54,8 12,8c3.46,0 6.62,1.26 9.07,3.34L20.54,12H14V20.13zM22.71,14.29L22.71,14.29c-0.38,-0.38 -1,-0.39 -1.38,0l-1.82,1.82l-1.82,-1.82c-0.38,-0.38 -1,-0.38 -1.38,0l-0.01,0.01c-0.38,0.38 -0.38,1 0,1.38l1.82,1.82l-1.83,1.83c-0.38,0.38 -0.38,1 0,1.38l0.01,0.01c0.38,0.38 1,0.38 1.38,0l1.83,-1.83l1.83,1.83c0.38,0.38 1,0.38 1.38,0v0c0.38,-0.38 0.38,-1 0,-1.38l-1.83,-1.83l1.83,-1.83C23.09,15.29 23.09,14.67 22.71,14.29z"
+ android:fillColor="#FFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml
index 136a004..2eae8f5 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_4.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -14,14 +14,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:pathData="M13.8,12.2l5.7,0.0L23.6,7.0C23.2,6.7 18.7,3.0 12.0,3.0C5.3,3.0 0.8,6.7 0.4,7.0L12.0,21.5l0.0,0.0l0.0,0.0l1.8,-2.2L13.8,12.2z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M21.9,15.4l-1.1,-1.2 -1.9,1.900001 -1.9,-1.900001 -1.1,1.2 1.9,1.9 -1.9,1.800001 1.1,1.199999 1.9,-1.9 1.9,1.9 1.1,-1.199999 -1.9,-1.800001z"
- android:fillColor="#FFFFFF"/>
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="25.50"
+ android:viewportHeight="25.50">
+ <group
+ android:translateX="0.77"
+ android:translateY="0.23" >
+ <path
+ android:pathData="M22.71,15.67l-1.83,1.83l1.83,1.83c0.38,0.38 0.38,1 0,1.38v0c-0.38,0.38 -1,0.39 -1.38,0l-1.83,-1.83l-1.83,1.83c-0.38,0.38 -1,0.38 -1.38,0l-0.01,-0.01c-0.38,-0.38 -0.38,-1 0,-1.38l1.83,-1.83l-1.82,-1.82c-0.38,-0.38 -0.38,-1 0,-1.38l0.01,-0.01c0.38,-0.38 1,-0.38 1.38,0l1.82,1.82l1.82,-1.82c0.38,-0.38 1,-0.38 1.38,0l0,0C23.09,14.67 23.09,15.29 22.71,15.67zM14,12h6.54l3.12,-3.89c0.39,-0.48 0.28,-1.19 -0.23,-1.54C21.66,5.36 17.55,3 12,3C6.44,3 2.33,5.36 0.56,6.57C0.05,6.92 -0.05,7.63 0.33,8.11L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L14,20.13V12z"
+ android:fillColor="#FFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
index 7993c80..95345b8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_detail_empty.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,14 +14,17 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="56dp"
- android:height="56dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0"
- android:alpha="0.14"
- android:tint="?android:attr/colorForeground">
-
- <path
- android:pathData="M24.0,4.0C15.0,4.0 6.7,7.0 0.0,12.0l24.0,32.0l24.0,-32.0C41.3,7.0 33.0,4.0 24.0,4.0z"
- android:fillColor="#FFFFFF" />
+ android:width="56dp"
+ android:height="56dp"
+ android:viewportWidth="25.0"
+ android:viewportHeight="23.5"
+ android:alpha="0.14"
+ android:tint="?android:attr/colorForeground" >
+ <group
+ android:translateX="0.51"
+ android:translateY="-1.1">
+ <path
+ android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+ android:fillColor="#FFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
index 30c10dc..ea02ba7 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disabled.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,14 +14,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
+ android:width="32dp"
android:height="29.5dp"
- android:viewportWidth="26.0"
- android:viewportHeight="24.0">
+ android:viewportWidth="25.6"
+ android:viewportHeight="23.6">
<group
- android:translateY="2">
+ android:translateX="0.8"
+ android:translateY="1.1">
<path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+ android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+ android:fillColor="#FFFFFFFF"/>
</group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml
index 2dcdb71..cb87cae 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_disconnected.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -14,29 +14,19 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="26.0dp"
- android:height="24.0dp"
- android:viewportWidth="26.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M21.0,8.5
- c0.85,0.0 1.6,0.23 2.3,0.62l2.24,-2.79
- C25.1,5.96 20.26,2.0 13.0,2.0
- S0.9,5.9 0.42,6.32
- l12.57,15.6 4.21,-5.17
- c-0.76,-0.87 -1.22,-2.0 -1.22,-3.25
- c0.0,-2.76 2.24,-5.0 5.0,-5.0z"
- android:fillAlpha=".3"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M21.0,10.0
- c-1.93,0.0 -3.5,1.57 -3.5,3.5l1.75,0.0
- c0.0,-0.9 0.78,-1.75 1.75,-1.75s1.7,0.78 1.75,1.75
- c0.0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1
- c-0.6,0.63 -1.02,1.51 -1.02,2.47l0.0,0.44l1.75,0.0
- c0.0,-1.3 0.39,-1.84 1.03,-2.47l0.78,-0.8
- c0.5,-0.5 0.82,-1.2 0.82,-1.97
- C24.5,11.57 22.93,10.0 21.0,10.0z
- m-0.95,11.95l1.9,0.0l0.0,-1.9l-1.9,0.0l0.0,1.9z"/>
+ android:width="26dp"
+ android:height="24dp"
+ android:viewportWidth="25.6"
+ android:viewportHeight="23.7">
+ <group
+ android:translateX="0.82"
+ android:translateY="-1">
+ <path
+ android:pathData="M18.9,20.85c0,-0.61 0.49,-1.1 1.1,-1.1 0.61,0 1.1,0.49 1.1,1.1 0,0.61 -0.49,1.1 -1.1,1.1 -0.61,0 -1.1,-0.49 -1.1,-1.1zM20,10c-1.53,0 -2.84,0.99 -3.31,2.36 -0.19,0.56 0.23,1.14 0.81,1.14 0.36,0 0.72,-0.21 0.84,-0.55 0.23,-0.7 0.89,-1.2 1.66,-1.2 0.97,0 1.75,0.78 1.75,1.75 0,0.48 -0.2,0.92 -0.51,1.24l-1.09,1.1c-0.69,0.69 -0.92,1.38 -0.99,2.2 -0.04,0.51 0.36,0.96 0.88,0.96 0.44,0 0.83,-0.33 0.87,-0.77 0.07,-0.79 0.31,-1.27 1,-1.95l0.78,-0.8c0.5,-0.5 0.82,-1.2 0.82,-1.97C23.5,11.57 21.93,10 20,10z"
+ android:fillColor="#FFFFFFFF"/>
+ <path
+ android:pathData="M14.73,12.88c0,-2.7 2.19,-4.88 4.88,-4.88 1.22,0 2.32,0.46 3.18,1.2l0.88,-1.09c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0l3.88,-4.82a4.862,4.862 0,0 1,-1.97 -3.9z"
+ android:fillAlpha="0.3"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
index 1bc7438..53e4efc 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_0.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,11 +14,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="29.5dp"
- android:viewportWidth="26.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+ android:width="32.0dp"
+ android:height="29.5dp"
+ android:viewportWidth="25.6"
+ android:viewportHeight="23.6">
+ <group
+ android:translateX="0.8"
+ android:translateY="-0.9">
+ <path
+ android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+ android:fillColor="#4DFFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
index 5856115..8294183 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_1.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,14 +14,18 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="29.5dp"
- android:viewportWidth="26.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M13.100000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.500000,6.500000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13.100000,22.000000l5.500000,-6.800000c-0.200000,-0.200000 -2.300000,-1.900000 -5.500000,-1.900000s-5.300000,1.800000 -5.500000,1.900000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000L13.100000,22.000000z"/>
+ android:width="32dp"
+ android:height="29.5dp"
+ android:viewportWidth="25.6"
+ android:viewportHeight="23.6">
+ <group
+ android:translateX="0.8"
+ android:translateY="-0.9">
+ <path
+ android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M12.82,21.6l5.11,-6.36A8.942,8.942 0,0 0,12 13c-2.28,0 -4.35,0.85 -5.94,2.25l5.1,6.35c0.43,0.53 1.23,0.53 1.66,0z"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
index 4a5e1f8..3d59cf2 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_2.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,14 +14,18 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="29.5dp"
- android:viewportWidth="26.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13.000000,22.000000l7.600000,-9.400000C20.299999,12.400000 17.400000,10.000000 13.000000,10.000000s-7.300000,2.400000 -7.600000,2.700000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+ android:width="32dp"
+ android:height="29.5dp"
+ android:viewportWidth="25.6"
+ android:viewportHeight="23.6">
+ <group
+ android:translateX="0.8"
+ android:translateY="-0.9">
+ <path
+ android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M12.82,21.6l6.99,-8.7C17.71,11.1 14.99,10 12,10c-2.99,0 -5.72,1.1 -7.82,2.91l6.98,8.7c0.43,0.52 1.23,0.52 1.66,-0.01z"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
index 965442d..21313b8 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_3.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,14 +14,18 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="29.5dp"
- android:viewportWidth="26.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#4DFFFFFF"
- android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13.000000,22.000000l9.200000,-11.400000c-0.400000,-0.300000 -3.900000,-3.200000 -9.200000,-3.200000s-8.900000,3.000000 -9.200000,3.200000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+ android:width="32dp"
+ android:height="29.5dp"
+ android:viewportWidth="25.6"
+ android:viewportHeight="23.6">
+ <group
+ android:translateX="0.8"
+ android:translateY="-0.9">
+ <path
+ android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+ android:fillColor="#4DFFFFFF"/>
+ <path
+ android:pathData="M12.82,21.6l8.25,-10.26A13.961,13.961 0,0 0,12 8c-3.46,0 -6.63,1.26 -9.07,3.35l8.23,10.26c0.43,0.52 1.23,0.52 1.66,-0.01z"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml b/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
index b29d3f9..fd763ff 100644
--- a/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_wifi_full_4.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,11 +14,15 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="29.5dp"
- android:viewportWidth="26.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M13.000000,22.000000L25.600000,6.500000C25.100000,6.100000 20.299999,2.100000 13.000000,2.100000S0.900000,6.100000 0.400000,6.500000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000L13.000000,22.000000z"/>
+ android:width="32dp"
+ android:height="29.5dp"
+ android:viewportWidth="25.6"
+ android:viewportHeight="23.6">
+ <group
+ android:translateX="0.8"
+ android:translateY="-0.9">
+ <path
+ android:pathData="M23.66,8.11c0.39,-0.48 0.29,-1.19 -0.22,-1.54C21.67,5.36 17.55,3 12,3 6.44,3 2.33,5.36 0.56,6.57c-0.51,0.35 -0.61,1.06 -0.23,1.54L11.16,21.6c0.42,0.53 1.23,0.53 1.66,0L23.66,8.11z"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings.xml b/packages/SystemUI/res/drawable/ic_settings.xml
index 9c78742..6d24c7e 100644
--- a/packages/SystemUI/res/drawable/ic_settings.xml
+++ b/packages/SystemUI/res/drawable/ic_settings.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
+<!-- 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"+
@@ -13,14 +13,11 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
-android:width="24dp"
-android:height="24dp" android:viewportWidth="24.0"
- android:viewportHeight="24.0">
-
-
-<path
- android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z"
- android:fillColor="#ffffffff"
- />
-
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M21.4,14.2l-1.94,-1.45c0.03,-0.25 0.04,-0.5 0.04,-0.76s-0.01,-0.51 -0.04,-0.76L21.4,9.8c0.42,-0.31 0.52,-0.94 0.24,-1.41l-1.6,-2.76c-0.28,-0.48 -0.88,-0.7 -1.36,-0.5l-2.14,0.91c-0.48,-0.37 -1.01,-0.68 -1.57,-0.92l-0.27,-2.2c-0.06,-0.52 -0.56,-0.92 -1.11,-0.92h-3.18c-0.55,0 -1.05,0.4 -1.11,0.92l-0.26,2.19c-0.57,0.24 -1.1,0.55 -1.58,0.92l-2.14,-0.91c-0.48,-0.2 -1.08,0.02 -1.36,0.5l-1.6,2.76c-0.28,0.48 -0.18,1.1 0.24,1.42l1.94,1.45c-0.03,0.24 -0.04,0.49 -0.04,0.75s0.01,0.51 0.04,0.76L2.6,14.2c-0.42,0.31 -0.52,0.94 -0.24,1.41l1.6,2.76c0.28,0.48 0.88,0.7 1.36,0.5l2.14,-0.91c0.48,0.37 1.01,0.68 1.57,0.92l0.27,2.19c0.06,0.53 0.56,0.93 1.11,0.93h3.18c0.55,0 1.04,-0.4 1.11,-0.92l0.27,-2.19c0.56,-0.24 1.09,-0.55 1.57,-0.92l2.14,0.91c0.48,0.2 1.08,-0.02 1.36,-0.5l1.6,-2.76c0.28,-0.48 0.18,-1.1 -0.24,-1.42zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"
+ android:fillColor="#FFFFFFFF"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_settings_16dp.xml b/packages/SystemUI/res/drawable/ic_settings_16dp.xml
index c21b60c..e3ed229 100644
--- a/packages/SystemUI/res/drawable/ic_settings_16dp.xml
+++ b/packages/SystemUI/res/drawable/ic_settings_16dp.xml
@@ -1,5 +1,5 @@
<!--
- Copyright (C) 2016 The Android Open Source Project
+ 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.
@@ -19,6 +19,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z"
- android:fillColor="#ffffffff" />
+ android:pathData="M21.4,14.2l-1.94,-1.45c0.03,-0.25 0.04,-0.5 0.04,-0.76s-0.01,-0.51 -0.04,-0.76L21.4,9.8c0.42,-0.31 0.52,-0.94 0.24,-1.41l-1.6,-2.76c-0.28,-0.48 -0.88,-0.7 -1.36,-0.5l-2.14,0.91c-0.48,-0.37 -1.01,-0.68 -1.57,-0.92l-0.27,-2.2c-0.06,-0.52 -0.56,-0.92 -1.11,-0.92h-3.18c-0.55,0 -1.05,0.4 -1.11,0.92l-0.26,2.19c-0.57,0.24 -1.1,0.55 -1.58,0.92l-2.14,-0.91c-0.48,-0.2 -1.08,0.02 -1.36,0.5l-1.6,2.76c-0.28,0.48 -0.18,1.1 0.24,1.42l1.94,1.45c-0.03,0.24 -0.04,0.49 -0.04,0.75s0.01,0.51 0.04,0.76L2.6,14.2c-0.42,0.31 -0.52,0.94 -0.24,1.41l1.6,2.76c0.28,0.48 0.88,0.7 1.36,0.5l2.14,-0.91c0.48,0.37 1.01,0.68 1.57,0.92l0.27,2.19c0.06,0.53 0.56,0.93 1.11,0.93h3.18c0.55,0 1.04,-0.4 1.11,-0.92l0.27,-2.19c0.56,-0.24 1.09,-0.55 1.57,-0.92l2.14,0.91c0.48,0.2 1.08,-0.02 1.36,-0.5l1.6,-2.76c0.28,-0.48 0.18,-1.1 -0.24,-1.42zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"
+ android:fillColor="#FFFFFFFF"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane.xml b/packages/SystemUI/res/drawable/ic_signal_airplane.xml
new file mode 100644
index 0000000..50dd436
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_airplane.xml
@@ -0,0 +1,30 @@
+<?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="48dp"
+ android:height="48dp"
+ android:viewportWidth="20.5"
+ android:viewportHeight="20.5">
+ <group
+ android:translateX="0.985"
+ android:translateY="1.10">
+ <path
+ android:pathData="M16.01,9.87l-6.24,-3.9v-4.7C9.77,0.57 9.21,0 8.5,0S7.23,0.57 7.23,1.28v4.7L0.99,9.88c-0.37,0.23 -0.6,0.64 -0.6,1.08v0.41c0,0.29 0.29,0.5 0.55,0.41l6.27,-1.97v4.7l-1.37,1.02c-0.21,0.16 -0.34,0.41 -0.34,0.68v0.57c0,0.15 0.12,0.23 0.27,0.2 1.67,-0.47 1.12,-0.31 2.73,-0.78 1.03,0.3 1.7,0.49 2.72,0.78 0.15,0.03 0.27,-0.06 0.27,-0.2v-0.57c0,-0.27 -0.13,-0.52 -0.34,-0.68l-1.37,-1.02v-4.7l6.27,1.97c0.28,0.09 0.55,-0.12 0.55,-0.41v-0.41c0.01,-0.45 -0.23,-0.87 -0.59,-1.09z"
+ android:fillColor="#FF0"/>
+ </group>
+</vector>
+
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
deleted file mode 100644
index c4ac7ffb..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_disable.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:alpha="1.0"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48" >
- <group
- android:name="ic_signal_airplane"
- android:translateX="21.9995"
- android:translateY="25.73401" >
- <group
- android:name="ic_signal_airplane_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 37.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 0.324981689453,0.399978637695 0.324981689453,0.399978637695 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="0"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="plane"
- android:translateX="23.481"
- android:translateY="15.71151" >
- <path
- android:name="plane_1"
- android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml b/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
deleted file mode 100644
index b7ac0134..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_airplane_enable.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48" >
- <group
- android:name="ic_signal_airplane"
- android:translateX="21.9995"
- android:translateY="25.73401" >
- <group
- android:name="ic_signal_airplane_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 37.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 7.54049682617,3.9430847168 c 0.0,0.0 31.5749816895,31.4499664307 31.5749816895,31.4499664307 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="1"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="plane"
- android:translateX="23.481"
- android:translateY="18.71151" >
- <path
- android:name="plane_1"
- android:pathData="M 18.9439849854,7.98849487305 c 0.0,0.0 0.0,-4.0 0.0,-4.0 c 0.0,0.0 -16.0,-10.0 -16.0,-10.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,-1.70001220703 -1.30000305176,-3.0 -3.0,-3.0 c -1.69999694824,0.0 -3.0,1.29998779297 -3.0,3.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -16.0,10.0 -16.0,10.0 c 0.0,0.0 0.0,4.0 0.0,4.0 c 0.0,0.0 16.0,-5.0 16.0,-5.0 c 0.0,0.0 0.0,11.0 0.0,11.0 c 0.0,0.0 -4.0,3.0 -4.0,3.0 c 0.0,0.0 0.0,3.0 0.0,3.0 c 0.0,0.0 7.0,-2.0 7.0,-2.0 c 0.0,0.0 7.0,2.0 7.0,2.0 c 0.0,0.0 0.0,-3.0 0.0,-3.0 c 0.0,0.0 -4.0,-3.0 -4.0,-3.0 c 0.0,0.0 0.0,-11.0 0.0,-11.0 c 0.0,0.0 16.0,5.0 16.0,5.0 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight.xml
new file mode 100644
index 0000000..38979a8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_flashlight.xml
@@ -0,0 +1,29 @@
+<?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="48dp"
+ android:height="48dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <group
+ android:translateX="-0.05"
+ android:translateY="0.85" >
+ <path
+ android:pathData="M8.28,2h7.43c0.55,0 1,0.45 1,1v0.96L7.28,3.96L7.28,3c0,-0.55 0.45,-1 1,-1zM14.8,9.76L14.8,21c0,0.55 -0.45,1 -1,1h-3.61c-0.55,0 -1,-0.45 -1,-1L9.19,9.78c-2.2,-1.17 -1.91,-3.76 -1.91,-3.76L7.28,5.7h9.44v0.32s0.26,2.57 -1.92,3.74zM13.38,12.47c0,-0.76 -0.62,-1.38 -1.38,-1.38s-1.38,0.62 -1.38,1.38 0.62,1.38 1.38,1.38 1.38,-0.62 1.38,-1.38z"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
deleted file mode 100644
index 35844b7..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_disable.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:alpha="1.0"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48" >
- <group
- android:name="ic_signal_flashlight"
- android:translateX="21.9995"
- android:translateY="25.73401" >
- <group
- android:name="ic_signal_flashlight_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="0"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="flashlight"
- android:translateX="25.06235"
- android:translateY="22.48294" >
- <path
- android:name="light"
- android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml b/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
deleted file mode 100644
index c2215f1..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_flashlight_enable.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48" >
- <group
- android:name="ic_signal_flashlight"
- android:translateX="21.9995"
- android:translateY="25.73401" >
- <group
- android:name="ic_signal_flashlight_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 37.8337860107,-39.2975769043 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,40.9278411865 40.9884796143,40.9278411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-40.9392852783 -41.1884460449,-40.9392852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 29.7749786377,29.7999725342 29.7749786377,29.7999725342 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="1"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="flashlight"
- android:translateX="25.06235"
- android:translateY="22.48294" >
- <path
- android:name="light"
- android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location.xml b/packages/SystemUI/res/drawable/ic_signal_location.xml
new file mode 100644
index 0000000..2f60580
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_location.xml
@@ -0,0 +1,29 @@
+<?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="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <group
+ android:translateX="0.02"
+ android:translateY="0.82">
+ <path
+ android:pathData="M12,2C8.13,2 5,5.13 5,9c0,4.17 4.42,9.92 6.24,12.11 0.4,0.48 1.13,0.48 1.53,0C14.58,18.92 19,13.17 19,9c0,-3.87 -3.13,-7 -7,-7zM12,11.5a2.5,2.5 0,0 1,0 -5,2.5 2.5,0 0,1 0,5z"
+ android:fillColor="#FFFFFFFF"/>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_disable.xml b/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
deleted file mode 100644
index 439851d..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_disable.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:alpha="1.0"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48" >
- <group
- android:name="ic_signal_location"
- android:translateX="21.9995"
- android:translateY="25.73401" >
- <group
- android:name="ic_signal_location_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 38.8337860107,-40.4599914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 7.3759765625,7.55284118652 7.3759765625,7.55284118652 c 0.0,0.0 -2.61698913574,2.0938873291 -2.61698913574,2.0938873291 c 0.0,0.0 -7.57595825195,-7.56428527832 -7.57595825195,-7.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 0.374984741211,0.399978637695 0.374984741211,0.399978637695 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="0"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="location"
- android:translateX="23.481"
- android:translateY="18.71151" >
- <path
- android:name="pin"
- android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_location_enable.xml b/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
deleted file mode 100644
index d4b8673..0000000
--- a/packages/SystemUI/res/drawable/ic_signal_location_enable.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2014 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:name="root"
- android:height="48dp"
- android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48" >
- <group
- android:name="ic_signal_location"
- android:translateX="21.9995"
- android:translateY="25.73401" >
- <group
- android:name="ic_signal_location_pivot"
- android:translateX="-23.21545"
- android:translateY="-18.86649" >
- <clip-path
- android:name="mask"
- android:pathData="M 38.8337860107,-40.3974914551 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 40.9884796143,41.1153411865 40.9884796143,41.1153411865 c 0.0,0.0 -2.61700439453,2.0938873291 -2.61700439453,2.0938873291 c 0.0,0.0 -41.1884460449,-41.1267852783 -41.1884460449,-41.1267852783 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
- <group
- android:name="cross" >
- <path
- android:name="cross_1"
- android:pathData="M 6.44050598145,1.9430847168 c 0.0,0.0 33.5749816895,33.4499664307 33.5749816895,33.4499664307 "
- android:strokeColor="#FFFFFFFF"
- android:strokeAlpha="1"
- android:strokeWidth="3.5"
- android:fillColor="#00000000" />
- </group>
- <group
- android:name="location"
- android:translateX="23.481"
- android:translateY="18.71151" >
- <path
- android:name="pin"
- android:pathData="M 1.76899719238,-20.011505127 c -7.69999694824,0.0 -14.0,6.30000305176 -14.0,14.0 c 0.0,10.5 14.0,26.0 14.0,26.0 c 0.0,0.0 14.0,-15.5 14.0,-26.0 c 0.0,-7.69999694824 -6.30000305176,-14.0 -14.0,-14.0 Z M 1.76899719238,-1.01150512695 c -2.80000305176,0.0 -5.0,-2.19999694824 -5.0,-5.0 c 0.0,-2.80000305176 2.19999694824,-5.0 5.0,-5.0 c 2.80000305176,0.0 5.0,2.19999694824 5.0,5.0 c 0.0,2.80000305176 -2.19999694824,5.0 -5.0,5.0 Z"
- android:fillColor="#FFFFFFFF"
- android:fillAlpha="1" />
- </group>
- </group>
- </group>
-</vector>
diff --git a/packages/SystemUI/res/drawable/qs_background_primary.xml b/packages/SystemUI/res/drawable/qs_background_primary.xml
index 03bba53..4165830 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="@color/qs_background_dark"/>
+ <solid android:color="?android:attr/colorBackgroundFloating"/>
</shape>
</inset>
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
index e043836..c82eddc 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -14,41 +14,58 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:fitsSystemWindows="true"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone">
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fitsSystemWindows="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@android:color/black"
+ android:visibility="gone">
+ <!-- This progressbar is activated while we're switching users. -->
<ProgressBar
- android:id="@+id/countdown_progress"
- android:layout_width="match_parent"
- android:layout_height="@dimen/car_user_switcher_progress_bar_height"
- style="@style/CarUserSwitcher.ProgressBar"
- android:layout_marginTop="@dimen/car_user_switcher_progress_bar_margin_top"
- android:layout_alignParentTop="true"/>
-
- <com.android.systemui.statusbar.car.UserGridView
- android:id="@+id/user_grid"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/car_margin"
- android:layout_marginRight="@dimen/car_margin"
- android:layout_centerInParent="true" />
-
- <com.android.systemui.statusbar.car.PageIndicator
- android:id="@+id/user_switcher_page_indicator"
- android:layout_width="match_parent"
- android:layout_height="@dimen/car_page_indicator_dot_diameter"
- android:layout_marginTop="@dimen/car_page_indicator_margin_top"
- android:layout_below="@+id/user_grid" />
-
- <Button
- android:id="@+id/start_driving"
+ android:id="@+id/switching_users"
android:layout_width="wrap_content"
- android:layout_height="@dimen/car_start_driving_height"
- android:text="@string/start_driving"
- style="@style/CarUserSwitcher.StartDrivingButton"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true" />
-</RelativeLayout>
+ android:layout_height="wrap_content"
+ android:indeterminate="true"
+ android:visibility="gone"
+ android:layout_gravity="center" />
+
+ <RelativeLayout
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <!-- This progress bar is the countdown timer. -->
+ <ProgressBar
+ android:id="@+id/countdown_progress"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/car_user_switcher_progress_bar_height"
+ style="@style/CarUserSwitcher.ProgressBar"
+ android:layout_marginTop="@dimen/car_user_switcher_progress_bar_margin_top"
+ android:layout_alignParentTop="true"/>
+
+ <com.android.systemui.statusbar.car.UserGridView
+ android:id="@+id/user_grid"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/car_margin"
+ android:layout_marginRight="@dimen/car_margin"
+ android:layout_centerInParent="true" />
+
+ <com.android.systemui.statusbar.car.PageIndicator
+ android:id="@+id/user_switcher_page_indicator"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/car_page_indicator_dot_diameter"
+ android:layout_marginTop="@dimen/car_page_indicator_margin_top"
+ android:layout_below="@+id/user_grid" />
+
+ <Button
+ android:id="@+id/start_driving"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/car_start_driving_height"
+ android:text="@string/start_driving"
+ style="@style/CarUserSwitcher.StartDrivingButton"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true" />
+ </RelativeLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 143a462..ef9cf4a 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -39,7 +39,7 @@
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textStyle="italic"
- android:textColor="#ffffff"
+ android:textColor="?attr/bgProtectSecondaryTextColor"
android:textAppearance="?android:attr/textAppearanceSmall"
android:visibility="gone" />
@@ -49,7 +49,7 @@
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textStyle="italic"
- android:textColor="#ffffff"
+ android:textColor="?attr/bgProtectSecondaryTextColor"
android:textAppearance="?android:attr/textAppearanceSmall"
android:accessibilityLiveRegion="polite" />
@@ -68,7 +68,8 @@
android:layout_gravity="bottom|end"
android:src="@drawable/ic_camera_alt_24dp"
android:scaleType="center"
- android:contentDescription="@string/accessibility_camera_button" />
+ android:contentDescription="@string/accessibility_camera_button"
+ android:tint="?attr/bgProtectTextColor" />
<com.android.systemui.statusbar.KeyguardAffordanceView
android:id="@+id/left_button"
@@ -77,7 +78,8 @@
android:layout_gravity="bottom|start"
android:src="@drawable/ic_phone_24dp"
android:scaleType="center"
- android:contentDescription="@string/accessibility_phone_button" />
+ android:contentDescription="@string/accessibility_phone_button"
+ android:tint="?attr/bgProtectTextColor" />
<com.android.systemui.statusbar.phone.LockIcon
android:id="@+id/lock_icon"
@@ -86,7 +88,8 @@
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/ic_lock_24dp"
android:contentDescription="@string/accessibility_unlock_button"
- android:scaleType="center" />
+ android:scaleType="center"
+ android:tint="?attr/bgProtectTextColor" />
<include layout="@layout/keyguard_bottom_area_overlay" />
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index c5f2f4a..71a681c 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -63,7 +63,7 @@
android:gravity="center_vertical"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="#ffffff"
+ android:textColor="?attr/bgProtectSecondaryTextColor"
android:singleLine="true" />
</com.android.systemui.statusbar.phone.KeyguardStatusBarView>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index fb4ac04..62a1756 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -18,7 +18,6 @@
android:id="@+id/quick_settings_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="?android:attr/colorPrimaryDark"
android:clipToPadding="false"
android:clipChildren="false">
@@ -27,6 +26,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/qs_background_primary"
+ android:alpha="0.8"
android:elevation="4dp" />
<com.android.systemui.qs.QSPanel
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 66c5dd5..97376c3 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -35,7 +35,7 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="24dp"
+ android:layout_height="32dp"
android:layout_alignParentEnd="true"
android:clipChildren="false"
android:clipToPadding="false"
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 2e22943..25c87d3 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -32,6 +32,7 @@
android:layout_width="wrap_content"
android:paddingEnd="6dp"
android:src="@drawable/stat_sys_vpn_ic"
+ android:tint="@color/background_protect_secondary"
android:contentDescription="@string/accessibility_vpn_on"
/>
<FrameLayout
diff --git a/packages/SystemUI/res/layout/status_bar_alarm_group.xml b/packages/SystemUI/res/layout/status_bar_alarm_group.xml
index 78b580f..3528f9e 100644
--- a/packages/SystemUI/res/layout/status_bar_alarm_group.xml
+++ b/packages/SystemUI/res/layout/status_bar_alarm_group.xml
@@ -30,7 +30,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
- android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
+ android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
android:textSize="@dimen/qs_time_collapsed_size"
android:gravity="center_vertical"
systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 07a9a60..bef0830 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -27,7 +27,6 @@
<include
layout="@layout/keyguard_status_view"
- android:layout_height="wrap_content"
android:visibility="gone" />
<com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer
diff --git a/packages/SystemUI/res/layout/status_bar_no_notifications.xml b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
index 6f87184..ed4bc67 100644
--- a/packages/SystemUI/res/layout/status_bar_no_notifications.xml
+++ b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
@@ -27,7 +27,7 @@
android:layout_height="64dp"
android:paddingTop="28dp"
android:gravity="top|center_horizontal"
- android:textColor="#e6ffffff"
+ android:textColor="?attr/bgProtectTextColor"
android:textSize="16sp"
android:text="@string/empty_shade_text"/>
</com.android.systemui.statusbar.EmptyShadeView>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
index efb273f..eefa9bc 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
@@ -30,5 +30,6 @@
android:focusable="true"
android:contentDescription="@string/accessibility_clear_all"
android:text="@string/clear_all_notifications_text"
+ android:textColor="?attr/bgProtectTextColor"
android:textAllCaps="true"/>
</com.android.systemui.statusbar.DismissView>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index ce57bf9..81f0138 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -127,5 +127,7 @@
<attr name="lightIconTheme" format="reference" />
<attr name="darkIconTheme" format="reference" />
+ <attr name="bgProtectTextColor" format="color" />
+ <attr name="bgProtectSecondaryTextColor" format="color" />
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 340cd79..d71bfca 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -815,4 +815,7 @@
<dimen name="qs_gutter_height">6dp</dimen>
+ <!-- Intended corner radius when drawing the mobile signal -->
+ <dimen name="stat_sys_mobile_signal_corner_radius">0.75dp</dimen>
+
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f3ce40f..a1bf3a2 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1455,6 +1455,9 @@
Hints that the user's only option is to block all of the app's notifications. -->
<string name="notification_default_channel_desc">This app doesn\'t have notification categories</string>
+ <!-- Notification: Control panel: Label that displays when the app's notifications cannot be blocked. -->
+ <string name="notification_unblockable_desc">Notifications from this app can\'t be turned off</string>
+
<!-- Notification: Control panel: Label that shows how many channels this application has
defined, describing the current notification channel as "1 out of n notification categories from this app". -->
<plurals name="notification_num_channels_desc">
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index b046256..f942be6 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -155,16 +155,16 @@
<style name="TextAppearance.StatusBar.Expanded.Clock">
<item name="android:textSize">@dimen/qs_time_expanded_size</item>
- <item name="android:fontFamily">sans-serif-condensed</item>
+ <item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textStyle">normal</item>
</style>
<style name="TextAppearance.StatusBar.Expanded.Date">
- <item name="android:textSize">@dimen/qs_date_collapsed_size</item>
+ <item name="android:textSize">@dimen/qs_time_expanded_size</item>
<item name="android:textStyle">normal</item>
- <item name="android:textColor">?android:attr/textColorSecondary</item>
- <item name="android:fontFamily">sans-serif-condensed</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:fontFamily">sans-serif</item>
</style>
<style name="TextAppearance.StatusBar.Expanded.AboveDateTime">
@@ -293,7 +293,18 @@
<style name="systemui_theme" parent="@*android:style/Theme.DeviceDefault.QuickSettings">
<item name="lightIconTheme">@style/DualToneLightTheme</item>
<item name="darkIconTheme">@style/DualToneDarkTheme</item>
+ <item name="bgProtectTextColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="bgProtectSecondaryTextColor">?android:attr/textColorSecondaryInverse</item>
+ <item name="pinDividerColor">@color/pin_divider_color</item>
+ <item name="pinDeleteColor">@color/pin_delete_color</item>
+ <item name="*android:lockPatternStyle">@style/LockPatternStyle</item>
</style>
+
+ <style name="LockPatternStyle">
+ <item name="*android:regularColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="*android:successColor">?android:attr/textColorPrimaryInverse</item>
+ </style>
+
<style name="qs_theme" parent="systemui_theme">
<item name="lightIconTheme">@style/QSIconTheme</item>
<item name="darkIconTheme">@style/QSIconTheme</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 616e5b9..165ca2a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -75,8 +75,7 @@
}
public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
- super(new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault), attrs,
- defStyle);
+ super(context, attrs, defStyle);
mSecurityModel = new KeyguardSecurityModel(context);
mLockPatternUtils = new LockPatternUtils(context);
mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index db1e8a9..2262869 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -21,7 +21,9 @@
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Color;
import android.os.UserHandle;
+import android.support.v4.graphics.ColorUtils;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.AttributeSet;
@@ -37,6 +39,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ChargingView;
+import com.android.systemui.statusbar.policy.DateView;
import java.util.Locale;
@@ -48,7 +51,7 @@
private final AlarmManager mAlarmManager;
private TextView mAlarmStatusView;
- private TextClock mDateView;
+ private DateView mDateView;
private TextClock mClockView;
private TextView mOwnerInfo;
private ViewGroup mClockContainer;
@@ -56,7 +59,8 @@
private View[] mVisibleInDoze;
private boolean mPulsing;
- private boolean mDark;
+ private float mDarkAmount;
+ private int mTextColor;
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@@ -118,12 +122,12 @@
mAlarmStatusView = findViewById(R.id.alarm_status);
mDateView = findViewById(R.id.date_view);
mClockView = findViewById(R.id.clock_view);
- mDateView.setShowCurrentUserTime(true);
mClockView.setShowCurrentUserTime(true);
mClockView.setAccessibilityDelegate(new KeyguardClockAccessibilityDelegate(mContext));
mOwnerInfo = findViewById(R.id.owner_info);
mBatteryDoze = findViewById(R.id.battery_doze);
mVisibleInDoze = new View[]{mBatteryDoze, mClockView};
+ mTextColor = mClockView.getCurrentTextColor();
boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
setEnableMarquee(shouldMarquee);
@@ -154,8 +158,7 @@
}
public void refreshTime() {
- mDateView.setFormat24Hour(Patterns.dateView);
- mDateView.setFormat12Hour(Patterns.dateView);
+ mDateView.setDatePattern(Patterns.dateViewSkel);
mClockView.setFormat12Hour(Patterns.clockView12);
mClockView.setFormat24Hour(Patterns.clockView24);
@@ -187,6 +190,10 @@
((MarginLayoutParams) mClockView.getLayoutParams()).bottomMargin;
}
+ public float getClockTextSize() {
+ return mClockView.getTextSize();
+ }
+
public static String formatNextAlarm(Context context, AlarmManager.AlarmClockInfo info) {
if (info == null) {
return "";
@@ -246,7 +253,7 @@
// DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often.
// This is an optimization to ensure we only recompute the patterns when the inputs change.
private static final class Patterns {
- static String dateView;
+ static String dateViewSkel;
static String clockView12;
static String clockView24;
static String cacheKey;
@@ -254,7 +261,7 @@
static void update(Context context, boolean hasAlarm) {
final Locale locale = Locale.getDefault();
final Resources res = context.getResources();
- final String dateViewSkel = res.getString(hasAlarm
+ dateViewSkel = res.getString(hasAlarm
? R.string.abbrev_wday_month_day_no_year_alarm
: R.string.abbrev_wday_month_day_no_year);
final String clockView12Skel = res.getString(R.string.clock_12hr_format);
@@ -262,8 +269,6 @@
final String key = locale.toString() + dateViewSkel + clockView12Skel + clockView24Skel;
if (key.equals(cacheKey)) return;
- dateView = DateFormat.getBestDateTimePattern(locale, dateViewSkel);
-
clockView12 = DateFormat.getBestDateTimePattern(locale, clockView12Skel);
// CLDR insists on adding an AM/PM indicator even though it wasn't in the skeleton
// format. The following code removes the AM/PM indicator if we didn't want it.
@@ -281,12 +286,13 @@
}
}
- public void setDark(boolean dark) {
- if (mDark == dark) {
+ public void setDark(float darkAmount) {
+ if (mDarkAmount == darkAmount) {
return;
}
- mDark = dark;
+ mDarkAmount = darkAmount;
+ boolean dark = darkAmount == 1;
final int N = mClockContainer.getChildCount();
for (int i = 0; i < N; i++) {
View child = mClockContainer.getChildAt(i);
@@ -297,6 +303,7 @@
}
updateDozeVisibleViews();
mBatteryDoze.setDark(dark);
+ mClockView.setTextColor(ColorUtils.blendARGB(mTextColor, Color.WHITE, darkAmount));
}
public void setPulsing(boolean pulsing) {
@@ -306,7 +313,7 @@
private void updateDozeVisibleViews() {
for (View child : mVisibleInDoze) {
- child.setAlpha(mDark && mPulsing ? 0.8f : 1);
+ child.setAlpha(mDarkAmount == 1 && mPulsing ? 0.8f : 1);
}
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index c43820d..7e81173 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
@@ -127,12 +128,13 @@
mCharPadding = a.getDimensionPixelSize(R.styleable.PasswordTextView_charPadding,
getContext().getResources().getDimensionPixelSize(
R.dimen.password_char_padding));
+ int textColor = a.getColor(R.styleable.PasswordTextView_android_textColor, Color.WHITE);
+ mDrawPaint.setColor(textColor);
} finally {
a.recycle();
}
mDrawPaint.setFlags(Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
mDrawPaint.setTextAlign(Paint.Align.CENTER);
- mDrawPaint.setColor(0xffffffff);
mDrawPaint.setTypeface(Typeface.create("sans-serif-light", 0));
mShowPassword = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.TEXT_SHOW_PASSWORD, 1) == 1;
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index cf8747e..6476416 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -71,6 +71,7 @@
private int mLightModeBackgroundColor;
private int mLightModeFillColor;
+ private float mDarkIntensity;
public BatteryMeterView(Context context) {
this(context, null, 0);
@@ -238,6 +239,7 @@
@Override
public void onDarkChanged(Rect area, float darkIntensity, int tint) {
+ mDarkIntensity = darkIntensity;
float intensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0;
int foreground = getColorForDarkIntensity(intensity, mLightModeFillColor,
mDarkModeFillColor);
@@ -254,6 +256,14 @@
}
}
+ public void setFillColor(int color) {
+ if (mLightModeFillColor == color) {
+ return;
+ }
+ mLightModeFillColor = color;
+ onDarkChanged(new Rect(), mDarkIntensity, DarkIconDispatcher.DEFAULT_ICON_TINT);
+ }
+
private int getColorForDarkIntensity(float darkIntensity, int lightColor, int darkColor) {
return (int) ArgbEvaluator.getInstance().evaluate(darkIntensity, lightColor, darkColor);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 3532f41..2d5d198 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -194,6 +194,12 @@
mKeyguardViewMediator.startKeyguardExitAnimation(startTime, fadeoutDuration);
Trace.endSection();
}
+
+ @Override
+ public void onShortPowerPressedGoHome() {
+ checkPermission();
+ mKeyguardViewMediator.onShortPowerPressedGoHome();
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7ccb431..b8de9f3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -2017,6 +2017,10 @@
Trace.endSection();
}
+ public void onShortPowerPressedGoHome() {
+ // do nothing
+ }
+
public ViewMediatorCallback getViewMediatorCallback() {
return mViewMediatorCallback;
}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
index ec5f9e7..493d244 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java
@@ -30,13 +30,13 @@
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
-import android.os.HandlerThread;
import android.os.Looper;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
@@ -166,7 +166,9 @@
}
if (!mPluginMap.containsKey(listener)) return;
mPluginMap.remove(listener).destroy();
- stopListening();
+ if (mPluginMap.size() == 0) {
+ stopListening();
+ }
}
private void startListening() {
@@ -237,7 +239,9 @@
mContext.getSystemService(NotificationManager.class).notifyAsUser(pkg,
SystemMessage.NOTE_PLUGIN, nb.build(), UserHandle.ALL);
}
- clearClassLoader(pkg);
+ if (clearClassLoader(pkg)) {
+ Toast.makeText(mContext, "Reloading " + pkg, Toast.LENGTH_LONG).show();
+ }
if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
for (PluginInstanceManager manager : mPluginMap.values()) {
manager.onPackageChange(pkg);
@@ -259,8 +263,8 @@
return classLoader;
}
- private void clearClassLoader(String pkg) {
- mClassLoaders.remove(pkg);
+ private boolean clearClassLoader(String pkg) {
+ return mClassLoaders.remove(pkg) != null;
}
ClassLoader getParentClassLoader() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
index c0509c1..2e7012e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java
@@ -37,7 +37,7 @@
/** Quick settings tile: Airplane mode **/
public class AirplaneModeTile extends QSTileImpl<BooleanState> {
private final Icon mIcon =
- ResourceIcon.get(R.drawable.ic_signal_airplane_disable);
+ ResourceIcon.get(R.drawable.ic_signal_airplane);
private final GlobalSetting mSetting;
private boolean mListening;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 74cc0ec..336c581 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -20,9 +20,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.service.quicksettings.Tile;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.style.RelativeSizeSpan;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
@@ -35,9 +32,7 @@
import android.widget.TextView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.BatteryInfo;
import com.android.settingslib.graph.BatteryMeterDrawableBase;
-import com.android.settingslib.graph.UsageView;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.DetailAdapter;
@@ -187,14 +182,6 @@
((ImageView) mCurrentView.findViewById(android.R.id.icon)).setImageDrawable(mDrawable);
Checkable checkbox = (Checkable) mCurrentView.findViewById(android.R.id.toggle);
checkbox.setChecked(mPowerSave);
- BatteryInfo.getBatteryInfo(mContext, new BatteryInfo.Callback() {
- @Override
- public void onBatteryInfoLoaded(BatteryInfo info) {
- if (mCurrentView != null) {
- bindBatteryInfo(info);
- }
- }
- });
final TextView batterySaverTitle =
(TextView) mCurrentView.findViewById(android.R.id.title);
final TextView batterySaverSummary =
@@ -216,23 +203,6 @@
}
}
- private void bindBatteryInfo(BatteryInfo info) {
- SpannableStringBuilder builder = new SpannableStringBuilder();
- builder.append(info.batteryPercentString, new RelativeSizeSpan(2.6f),
- Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
- if (info.remainingLabel != null) {
- if (mContext.getResources().getBoolean(R.bool.quick_settings_wide)) {
- builder.append(' ');
- } else {
- builder.append('\n');
- }
- builder.append(info.remainingLabel);
- }
- ((TextView) mCurrentView.findViewById(R.id.charge_and_estimation)).setText(builder);
-
- info.bindHistory((UsageView) mCurrentView.findViewById(R.id.battery_usage));
- }
-
@Override
public void onClick(View v) {
mBatteryController.setPowerSaveMode(!mPowerSave);
@@ -278,4 +248,4 @@
}
};
}
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
index 97a12c2..40fe484 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ColorInversionTile.java
@@ -34,7 +34,7 @@
/** Quick settings tile: Invert colors **/
public class ColorInversionTile extends QSTileImpl<BooleanState> {
- private final Icon mIcon = ResourceIcon.get(drawable.ic_invert_colors_disable);
+ private final Icon mIcon = ResourceIcon.get(drawable.ic_invert_colors);
private final SecureSetting mSetting;
private boolean mListening;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 8c6363a..71f253c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -71,8 +71,6 @@
private static final QSTile.Icon TOTAL_SILENCE =
ResourceIcon.get(R.drawable.ic_qs_dnd_on_total_silence);
- private final Icon mDisable = ResourceIcon.get(R.drawable.ic_qs_dnd_off);
-
private final ZenModeController mController;
private final DndDetailAdapter mDetailAdapter;
@@ -187,7 +185,7 @@
R.string.accessibility_quick_settings_dnd_alarms_on);
break;
default:
- state.icon = mDisable;
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
state.label = mContext.getString(R.string.quick_settings_dnd_label);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_dnd);
@@ -317,7 +315,7 @@
mZenPanel.init(mController);
mZenPanel.addOnAttachStateChangeListener(this);
mZenPanel.setCallback(mZenModePanelCallback);
- mZenPanel.setEmptyState(R.drawable.ic_qs_dnd_off, R.string.dnd_is_off);
+ mZenPanel.setEmptyState(R.drawable.ic_qs_dnd_detail_empty, R.string.dnd_is_off);
}
updatePanel();
return mZenPanel;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
index b436e17..e6ac908 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java
@@ -35,7 +35,7 @@
public class FlashlightTile extends QSTileImpl<BooleanState> implements
FlashlightController.FlashlightListener {
- private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight_disable);
+ private final Icon mIcon = ResourceIcon.get(R.drawable.ic_signal_flashlight);
private final FlashlightController mFlashlightController;
public FlashlightTile(QSHost host) {
@@ -103,9 +103,8 @@
}
state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label);
if (!mFlashlightController.isAvailable()) {
- Drawable icon = mHost.getContext().getDrawable(R.drawable.ic_signal_flashlight_enable)
- .mutate();
- state.icon = new DrawableIcon(icon);
+ state.icon = mIcon;
+ state.slash.isSlashed = true;
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_flashlight_unavailable);
state.state = Tile.STATE_UNAVAILABLE;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 1c7c578..c17573d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -39,7 +39,7 @@
static final Intent TETHER_SETTINGS = new Intent().setComponent(new ComponentName(
"com.android.settings", "com.android.settings.TetherSettings"));
- private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot_disable);
+ private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot);
private final Icon mUnavailable = ResourceIcon.get(R.drawable.ic_hotspot_unavailable);
private final HotspotController mController;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 96f2f68..5e66334 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -37,7 +37,7 @@
/** Quick settings tile: Location **/
public class LocationTile extends QSTileImpl<BooleanState> {
- private final Icon mIcon = ResourceIcon.get(drawable.ic_signal_location_disable);
+ private final Icon mIcon = ResourceIcon.get(drawable.ic_signal_location);
private final LocationController mController;
private final KeyguardMonitor mKeyguard;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 8aa1e43..2a12769 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -79,8 +79,7 @@
state.value = isActivated;
state.label = state.contentDescription =
mContext.getString(R.string.quick_settings_night_display_label);
- state.icon = ResourceIcon.get(isActivated ? R.drawable.ic_qs_night_display_on
- : R.drawable.ic_qs_night_display_off);
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_night_display_on);
state.expandedAccessibilityClassName = Switch.class.getName();
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 2d47c7b..a7b845e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -578,7 +578,8 @@
if (requiresRotation) {
// Rotate the screenshot to the current orientation
Bitmap ss = Bitmap.createBitmap(mDisplayMetrics.widthPixels,
- mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
+ mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888,
+ mScreenBitmap.hasAlpha(), mScreenBitmap.getColorSpace());
Canvas c = new Canvas(ss);
c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
c.rotate(degrees);
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 0b09acc..f750815 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -79,6 +79,7 @@
private void addDivider(Configuration configuration) {
mView = (DividerView)
LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
+ mView.injectDependencies(mWindowManager, mDividerState);
mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
final int size = mContext.getResources().getDimensionPixelSize(
@@ -87,7 +88,6 @@
final int width = landscape ? size : MATCH_PARENT;
final int height = landscape ? MATCH_PARENT : size;
mWindowManager.add(mView, width, height);
- mView.injectDependencies(mWindowManager, mDividerState);
}
private void removeDivider() {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
index 353a974..3a5c61e 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerState.java
@@ -22,4 +22,5 @@
public class DividerState {
public boolean animateAfterRecentsDrawn;
public boolean growAfterRecentsDrawn;
+ public float mRatioPositionBeforeMinimized;
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 9e2ec571fa..2bda1df 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -364,6 +364,17 @@
public void injectDependencies(DividerWindowManager windowManager, DividerState dividerState) {
mWindowManager = windowManager;
mState = dividerState;
+
+ // Set the previous position ratio before minimized state after attaching this divider
+ if (mStableInsets.isEmpty()) {
+ SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
+ }
+ int position = (int) (mState.mRatioPositionBeforeMinimized *
+ (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth));
+ mSnapAlgorithm = null;
+ initializeSnapAlgorithm();
+ mDividerPositionBeforeMinimized = mSnapAlgorithm.calculateNonDismissingSnapTarget(position)
+ .position;
}
public WindowManagerProxy getWindowManagerProxy() {
@@ -719,19 +730,12 @@
mHandle.setAlpha(minimized ? 0f : 1f);
mDockedStackMinimized = minimized;
} else if (mDockedStackMinimized != minimized) {
- if (mStableInsets.isEmpty()) {
- SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
- }
mMinimizedSnapAlgorithm = null;
mDockedStackMinimized = minimized;
initializeSnapAlgorithm();
if (mIsInMinimizeInteraction != minimized) {
if (minimized) {
mIsInMinimizeInteraction = true;
- mDividerPositionBeforeMinimized = DockedDividerUtils.calculateMiddlePosition(
- isHorizontalDivision(), mStableInsets, mDisplayWidth, mDisplayHeight,
- mDividerSize);
-
int position = mMinimizedSnapAlgorithm.getMiddleTarget().position;
resizeStack(position, position, mMinimizedSnapAlgorithm.getMiddleTarget());
} else {
@@ -776,7 +780,7 @@
mIsInMinimizeInteraction = true;
if (minimized && (mCurrentAnimator == null || !mCurrentAnimator.isRunning())
&& (mDividerPositionBeforeMinimized <= 0 || !mAdjustedForIme)) {
- mDividerPositionBeforeMinimized = getCurrentPosition();
+ savePositionBeforeMinimized();
}
mMinimizedSnapAlgorithm = null;
mDockedStackMinimized = minimized;
@@ -836,10 +840,16 @@
// Only get new position if home stack is resizable, ime is open and not minimized
// (including the animation)
if (mHomeStackResizable && adjustedForIme && !mIsInMinimizeInteraction) {
- mDividerPositionBeforeMinimized = getCurrentPosition();
+ savePositionBeforeMinimized();
}
}
+ private void savePositionBeforeMinimized() {
+ mDividerPositionBeforeMinimized = getCurrentPosition();
+ mState.mRatioPositionBeforeMinimized = (float) mDividerPositionBeforeMinimized /
+ (isHorizontalDivision() ? mDisplayHeight : mDisplayWidth);
+ }
+
private void resetBackground() {
mBackground.setPivotX(mBackground.getWidth() / 2);
mBackground.setPivotY(mBackground.getHeight() / 2);
@@ -1198,14 +1208,6 @@
mDockSide, mDividerSize);
mEntranceAnimationRunning = true;
- // Insets might not have been fetched yet, so fetch manually if needed.
- if (mStableInsets.isEmpty()) {
- SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets);
- mSnapAlgorithm = null;
- mMinimizedSnapAlgorithm = null;
- initializeSnapAlgorithm();
- }
-
resizeStack(position, mSnapAlgorithm.getMiddleTarget().position,
mSnapAlgorithm.getMiddleTarget());
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
index a2c782e..578a18a 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java
@@ -142,7 +142,9 @@
Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class);
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchTaskId(pendingRecord.taskId);
- options.setTaskOverlay(true, false /* canResume */);
+ // Set as task overlay and allow to resume, so that when an app enters split-screen and
+ // becomes paused, the overlay will still be shown.
+ options.setTaskOverlay(true, true /* canResume */);
intent.putExtra(EXTRA_FORCED_RESIZEABLE_REASON, pendingRecord.reason);
mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index b15f090..e12b574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -23,6 +23,7 @@
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.CanvasProperty;
import android.graphics.Color;
@@ -55,7 +56,7 @@
private final int mMinBackgroundRadius;
private final Paint mCirclePaint;
- private final int mInverseColor;
+ private final int mDarkIconColor;
private final int mNormalColor;
private final ArgbEvaluator mColorInterpolator;
private final FlingAnimationUtils mFlingAnimationUtils;
@@ -126,17 +127,21 @@
public KeyguardAffordanceView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ TypedArray a = context.obtainStyledAttributes(attrs, android.R.styleable.ImageView);
+
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCircleColor = 0xffffffff;
mCirclePaint.setColor(mCircleColor);
- mNormalColor = 0xffffffff;
- mInverseColor = 0xff000000;
+ mNormalColor = a.getColor(android.R.styleable.ImageView_tint, 0xffffffff);
+ mDarkIconColor = 0xff000000;
mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
R.dimen.keyguard_affordance_min_background_radius);
mColorInterpolator = new ArgbEvaluator();
mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.3f);
+
+ a.recycle();
}
public void setImageDrawable(@Nullable Drawable drawable, boolean tint) {
@@ -177,7 +182,7 @@
Drawable drawable = getDrawable().mutate();
float alpha = mCircleRadius / mMinBackgroundRadius;
alpha = Math.min(1.0f, alpha);
- int color = (int) mColorInterpolator.evaluate(alpha, mNormalColor, mInverseColor);
+ int color = (int) mColorInterpolator.evaluate(alpha, mNormalColor, mDarkIconColor);
drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 49c3f7e..25ef478 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -65,21 +65,22 @@
private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
private final Context mContext;
- private final ViewGroup mIndicationArea;
- private final KeyguardIndicationTextView mTextView;
- private final KeyguardIndicationTextView mDisclosure;
+ private ViewGroup mIndicationArea;
+ private KeyguardIndicationTextView mTextView;
+ private KeyguardIndicationTextView mDisclosure;
private final UserManager mUserManager;
private final IBatteryStats mBatteryInfo;
private final SettableWakeLock mWakeLock;
private final int mSlowThreshold;
private final int mFastThreshold;
- private final LockIcon mLockIcon;
+ private LockIcon mLockIcon;
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private String mRestingIndication;
private String mTransientIndication;
private int mTransientTextColor;
+ private int mInitialTextColor;
private boolean mVisible;
private boolean mPowerPluggedIn;
@@ -114,6 +115,7 @@
mIndicationArea = indicationArea;
mTextView = (KeyguardIndicationTextView) indicationArea.findViewById(
R.id.keyguard_indication_text);
+ mInitialTextColor = mTextView != null ? mTextView.getCurrentTextColor() : Color.WHITE;
mDisclosure = (KeyguardIndicationTextView) indicationArea.findViewById(
R.id.keyguard_indication_enterprise_disclosure);
mLockIcon = lockIcon;
@@ -238,7 +240,7 @@
* Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
*/
public void showTransientIndication(String transientIndication) {
- showTransientIndication(transientIndication, Color.WHITE);
+ showTransientIndication(transientIndication, mInitialTextColor);
}
/**
@@ -273,13 +275,17 @@
}
if (mVisible) {
- // Walk down a precedence-ordered list of what should indication
+ // Walk down a precedence-ordered list of what indication
// should be shown based on user or device state
if (mDozing) {
// If we're dozing, never show a persistent indication.
if (!TextUtils.isEmpty(mTransientIndication)) {
+ // When dozing we ignore the initial text color and use white instead.
+ // We don't wait to draw black text on a black background.
+ int color = mTransientTextColor == mInitialTextColor ?
+ Color.WHITE : mTransientTextColor;
mTextView.switchIndication(mTransientIndication);
- mTextView.setTextColor(mTransientTextColor);
+ mTextView.setTextColor(color);
} else {
mTextView.switchIndication(null);
@@ -293,29 +299,29 @@
String trustManagedIndication = getTrustManagedIndication();
if (!mUserManager.isUserUnlocked(userId)) {
mTextView.switchIndication(com.android.internal.R.string.lockscreen_storage_locked);
- mTextView.setTextColor(Color.WHITE);
+ mTextView.setTextColor(mInitialTextColor);
} else if (!TextUtils.isEmpty(mTransientIndication)) {
mTextView.switchIndication(mTransientIndication);
mTextView.setTextColor(mTransientTextColor);
} else if (!TextUtils.isEmpty(trustGrantedIndication)
&& updateMonitor.getUserHasTrust(userId)) {
mTextView.switchIndication(trustGrantedIndication);
- mTextView.setTextColor(Color.WHITE);
+ mTextView.setTextColor(mInitialTextColor);
} else if (mPowerPluggedIn) {
String indication = computePowerIndication();
if (DEBUG_CHARGING_SPEED) {
indication += ", " + (mChargingWattage / 1000) + " mW";
}
mTextView.switchIndication(indication);
- mTextView.setTextColor(Color.WHITE);
+ mTextView.setTextColor(mInitialTextColor);
} else if (!TextUtils.isEmpty(trustManagedIndication)
&& updateMonitor.getUserTrustIsManaged(userId)
&& !updateMonitor.getUserHasTrust(userId)) {
mTextView.switchIndication(trustManagedIndication);
- mTextView.setTextColor(Color.WHITE);
+ mTextView.setTextColor(mInitialTextColor);
} else {
mTextView.switchIndication(mRestingIndication);
- mTextView.setTextColor(Color.WHITE);
+ mTextView.setTextColor(mInitialTextColor);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 427708b..1ffb3b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -154,9 +154,32 @@
}
}
+ boolean nonBlockable = false;
+ try {
+ final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
+ if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) {
+ final int numChannels = mNotificationChannels.size();
+ for (int i = 0; i < numChannels; i++) {
+ final NotificationChannel notificationChannel = mNotificationChannels.get(i);
+ // If any of the system channels is not blockable, the bundle is nonblockable
+ if (!notificationChannel.isBlockableSystem()) {
+ nonBlockable = true;
+ break;
+ }
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // unlikely.
+ }
+ if (nonBlockablePkgs != null) {
+ nonBlockable |= nonBlockablePkgs.contains(pkg);
+ }
+
String channelsDescText;
mNumChannelsView = findViewById(R.id.num_channels_desc);
- if (mIsSingleDefaultChannel) {
+ if (nonBlockable) {
+ channelsDescText = mContext.getString(R.string.notification_unblockable_desc);
+ } else if (mIsSingleDefaultChannel) {
channelsDescText = mContext.getString(R.string.notification_default_channel_desc);
} else {
switch (mNotificationChannels.size()) {
@@ -188,8 +211,9 @@
// Multiple channels don't use a channel name for the title.
channelNameText = mContext.getString(R.string.notification_num_channels,
mNotificationChannels.size());
- } else if (mIsSingleDefaultChannel) {
- // If this is the default channel, don't use our channel-specific text.
+ } else if (mIsSingleDefaultChannel || nonBlockable) {
+ // If this is the default channel or the app is unblockable,
+ // don't use our channel-specific text.
channelNameText = mContext.getString(R.string.notification_header_default_channel);
} else {
channelNameText = mSingleNotificationChannel.getName();
@@ -218,19 +242,6 @@
groupDividerView.setVisibility(View.GONE);
}
- boolean nonBlockable = false;
- try {
- final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
- nonBlockable = Utils.isSystemPackage(getResources(), pm, pkgInfo)
- && (mSingleNotificationChannel == null
- || !mSingleNotificationChannel.isBlockableSystem());
- } catch (PackageManager.NameNotFoundException e) {
- // unlikely.
- }
- if (nonBlockablePkgs != null) {
- nonBlockable |= nonBlockablePkgs.contains(pkg);
- }
-
bindButtons(nonBlockable);
// Top-level importance group
@@ -246,12 +257,11 @@
(View view) -> {
onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF);
});
- if (numTotalChannels > 1) {
- settingsButton.setText(R.string.notification_all_categories);
- } else {
+ if (numTotalChannels <= 1 || nonBlockable) {
settingsButton.setText(R.string.notification_more_settings);
+ } else {
+ settingsButton.setText(R.string.notification_all_categories);
}
-
} else {
settingsButton.setVisibility(View.GONE);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 7a741ef..14374b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -170,7 +170,7 @@
openedAmount = Math.min(1.0f, openedAmount);
mShelfState.openedAmount = openedAmount;
mShelfState.clipTopAmount = 0;
- mShelfState.alpha = mAmbientState.isPulsing() ? 0 : 1;
+ mShelfState.alpha = mAmbientState.hasPulsingNotifications() ? 0 : 1;
mShelfState.belowSpeedBump = mAmbientState.getSpeedBumpIndex() == 0;
mShelfState.shadowAlpha = 1.0f;
mShelfState.hideSensitive = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index ab41485..18cc8721 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -308,7 +308,7 @@
if (state == null) {
return;
}
- if (mQsSignal) {
+ if (mQsSignal && qsIcon != null) {
icon = qsIcon;
type = qsType;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index d84a731..9338887 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.car;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.content.res.Resources;
import android.os.CountDownTimer;
import android.view.View;
@@ -31,11 +33,16 @@
*/
public class FullscreenUserSwitcher {
private final View mContainer;
+ private final View mParent;
private final UserGridView mUserGridView;
private final UserSwitcherController mUserSwitcherController;
private final ProgressBar mProgressBar;
+ private final ProgressBar mSwitchingUsers;
private final int mLoginTimeoutMs;
private final int mAnimUpdateIntervalMs;
+ private final int mShortAnimDuration;
+
+ private boolean mShowing;
private CountDownTimer mTimer;
@@ -43,9 +50,15 @@
UserSwitcherController userSwitcherController,
ViewStub containerStub) {
mUserSwitcherController = userSwitcherController;
- mContainer = containerStub.inflate();
+ mParent = containerStub.inflate();
+ mContainer = mParent.findViewById(R.id.container);
mUserGridView = mContainer.findViewById(R.id.user_grid);
mUserGridView.init(statusBar, mUserSwitcherController);
+ mUserGridView.setUserSelectionListener(record -> {
+ if (!record.isCurrent) {
+ toggleSwitchInProgress(true);
+ }
+ });
PageIndicator pageIndicator = mContainer.findViewById(R.id.user_switcher_page_indicator);
pageIndicator.setupWithViewPager(mUserGridView);
@@ -54,20 +67,64 @@
Resources res = mContainer.getResources();
mLoginTimeoutMs = res.getInteger(R.integer.car_user_switcher_timeout_ms);
mAnimUpdateIntervalMs = res.getInteger(R.integer.car_user_switcher_anim_update_ms);
+ mShortAnimDuration = res.getInteger(android.R.integer.config_shortAnimTime);
mContainer.findViewById(R.id.start_driving).setOnClickListener(v -> {
cancelTimer();
automaticallySelectUser();
});
+
+ mSwitchingUsers = mParent.findViewById(R.id.switching_users);
}
public void onUserSwitched(int newUserId) {
mUserGridView.onUserSwitched(newUserId);
}
+ private void toggleSwitchInProgress(boolean inProgress) {
+ if (inProgress) {
+ crossFade(mSwitchingUsers, mContainer);
+ } else {
+ crossFade(mContainer, mSwitchingUsers);
+ }
+ }
+
+ private void crossFade(View incoming, View outgoing) {
+ incoming.animate()
+ .alpha(1.0f)
+ .setDuration(mShortAnimDuration)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animator) {
+ incoming.setAlpha(0.0f);
+ incoming.setVisibility(View.VISIBLE);
+ }
+ });
+
+ outgoing.animate()
+ .alpha(0.0f)
+ .setDuration(mShortAnimDuration)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ outgoing.setVisibility(View.GONE);
+ }
+ });
+ }
+
public void show() {
- mContainer.setVisibility(View.VISIBLE);
+ if (mShowing) {
+ return;
+ }
+ mShowing = true;
+ mParent.setVisibility(View.VISIBLE);
cancelTimer();
+
+ // This would be the case if we were in the middle of a switch.
+ if (mProgressBar.getVisibility() != View.VISIBLE) {
+ return;
+ }
+
mTimer = new CountDownTimer(mLoginTimeoutMs, mAnimUpdateIntervalMs) {
@Override
public void onTick(long msUntilFinished) {
@@ -85,8 +142,10 @@
}
public void hide() {
+ mShowing = false;
cancelTimer();
- mContainer.setVisibility(View.GONE);
+ toggleSwitchInProgress(false);
+ mParent.setVisibility(View.GONE);
}
private void cancelTimer() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
index 46f55eea..cfa9864 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
@@ -17,11 +17,12 @@
package com.android.systemui.statusbar.car;
import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -30,6 +31,7 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.internal.util.UserIcons;
import com.android.systemui.R;
import com.android.systemui.statusbar.UserUtil;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -43,7 +45,7 @@
private StatusBar mStatusBar;
private UserSwitcherController mUserSwitcherController;
private Adapter mAdapter;
- private int mPendingUserId = UserHandle.USER_NULL;
+ private UserSelectionListener mUserSelectionListener;
public UserGridView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -58,16 +60,12 @@
}
public void onUserSwitched(int newUserId) {
- if (mPendingUserId == newUserId) {
- // Bring up security view after user switch is completed.
- post(new Runnable() {
- @Override
- public void run() {
- showOfflineAuthUi();
- }
- });
- }
- mPendingUserId = UserHandle.USER_NULL;
+ // Bring up security view after user switch is completed.
+ post(this::showOfflineAuthUi);
+ }
+
+ public void setUserSelectionListener(UserSelectionListener userSelectionListener) {
+ mUserSelectionListener = userSelectionListener;
}
void showOfflineAuthUi() {
@@ -136,15 +134,19 @@
for (int i = position * iconsPerPage; i < limit; i++) {
pods.addView(makeUserPod(inflater, context, i, pods));
}
-
- // Dynamic parameters since we specify the weightsum dynamically.
- LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT,
- LinearLayout.LayoutParams.WRAP_CONTENT, limit);
- container.addView(pods, params);
+ container.addView(pods);
return pods;
}
+ private Drawable getUserIcon(Context context, UserSwitcherController.UserRecord record) {
+ if (record.isAddUser) {
+ Drawable icon = context.getDrawable(R.drawable.ic_add_circle_qs);
+ icon.setTint(Color.WHITE);
+ return icon;
+ }
+ return UserIcons.getDefaultUserIcon(record.resolveId(), /* light= */ true);
+ }
+
private View makeUserPod(LayoutInflater inflater, Context context,
int position, ViewGroup parent) {
final UserSwitcherController.UserRecord record = mUserAdapter.getItem(position);
@@ -160,45 +162,27 @@
ImageView iconView = (ImageView) view.findViewById(R.id.user_avatar);
if (record == null || record.picture == null) {
- iconView.setImageDrawable(mUserAdapter.getDrawable(context, record));
+ iconView.setImageDrawable(getUserIcon(context, record));
} else {
iconView.setImageBitmap(record.picture);
}
iconView.setOnClickListener(v -> {
- mPendingUserId = UserHandle.USER_NULL;
if (record == null) {
return;
}
- if (record.isGuest || record.isAddUser) {
- mUserSwitcherController.switchTo(record);
- return;
+ if (mUserSelectionListener != null) {
+ mUserSelectionListener.onUserSelected(record);
}
if (record.isCurrent) {
showOfflineAuthUi();
} else {
- mPendingUserId = record.info.id;
mUserSwitcherController.switchTo(record);
}
});
- iconView.setOnLongClickListener(v -> {
- if (record == null || record.isAddUser) {
- return false;
- }
- if (record.isGuest) {
- if (record.isCurrent) {
- mUserSwitcherController.switchTo(record);
- }
- return true;
- }
- UserUtil.deleteUserWithPrompt(getContext(), record.info.id,
- mUserSwitcherController);
- return true;
- });
-
return view;
}
@@ -247,4 +231,8 @@
mContainer.notifyDataSetChanged();
}
}
+
+ interface UserSelectionListener {
+ void onUserSelected(UserSwitcherController.UserRecord record);
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
index 020dc25..e0f577d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.java
@@ -15,36 +15,76 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.content.om.IOverlayManager;
import android.content.res.Configuration;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
import com.android.systemui.ConfigurationChangedReceiver;
import com.android.systemui.statusbar.policy.ConfigurationController;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
public class ConfigurationControllerImpl implements ConfigurationController,
ConfigurationChangedReceiver {
private final ArrayList<ConfigurationListener> mListeners = new ArrayList<>();
+ private final IOverlayManager mOverlayManager;
private int mDensity;
private float mFontScale;
+ private Map mActiveOverlays;
public ConfigurationControllerImpl(Context context) {
Configuration currentConfig = context.getResources().getConfiguration();
+ mOverlayManager = IOverlayManager.Stub.asInterface(
+ ServiceManager.getService(Context.OVERLAY_SERVICE));
mFontScale = currentConfig.fontScale;
mDensity = currentConfig.densityDpi;
+ try {
+ mActiveOverlays = mOverlayManager.getAllOverlays(UserHandle.getCallingUserId());
+ } catch (RemoteException e) {
+ mActiveOverlays = new HashMap();
+ }
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
- mListeners.forEach(l -> l.onConfigChanged(newConfig));
+ // Avoid concurrent modification exception
+ ArrayList<ConfigurationListener> listeners = new ArrayList<>(mListeners);
+
+ listeners.forEach(l -> {
+ if (mListeners.contains(l)) {
+ l.onConfigChanged(newConfig);
+ }
+ });
final float fontScale = newConfig.fontScale;
final int density = newConfig.densityDpi;
if (density != mDensity || mFontScale != fontScale) {
- mListeners.forEach(l -> l.onDensityOrFontScaleChanged());
+ listeners.forEach(l -> {
+ if (mListeners.contains(l)) {
+ l.onDensityOrFontScaleChanged();
+ }
+ });
mDensity = density;
mFontScale = fontScale;
}
+
+ try {
+ Map activeOverlays = mOverlayManager.getAllOverlays(UserHandle.getCallingUserId());
+ if (!mActiveOverlays.equals(activeOverlays)) {
+ mActiveOverlays = activeOverlays;
+ listeners.forEach(l -> {
+ if (mListeners.contains(l)) {
+ l.onOverlayChanged();
+ }
+ });
+ }
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 42b09df..6d6250e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -16,9 +16,12 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.ColorInt;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
@@ -28,6 +31,7 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import com.android.settingslib.Utils;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
@@ -312,4 +316,10 @@
public boolean hasOverlappingRendering() {
return false;
}
+
+ public void onOverlayChanged() {
+ @ColorInt int textColor = Utils.getColorAttr(mContext, R.attr.bgProtectTextColor);
+ mCarrierLabel.setTextColor(textColor);
+ mBatteryView.setFillColor(textColor);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 52838b0..b888e8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -235,4 +235,9 @@
v.setDecorColor(mIconTint);
}
}
+
+ public void setDark(boolean dark) {
+ mNotificationIcons.setDark(dark, false, 0);
+ mShelfIcons.setDark(dark, false, 0);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 3dc6827..e2b9da0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -34,6 +34,7 @@
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.MathUtils;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -47,8 +48,10 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.DejankUtils;
+import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
@@ -58,6 +61,7 @@
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.GestureRecorder;
import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.StatusBarState;
@@ -65,6 +69,7 @@
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -112,7 +117,6 @@
private QS mQs;
private FrameLayout mQsFrame;
private KeyguardStatusView mKeyguardStatusView;
- private TextView mClockView;
private View mReserveNotificationSpace;
private View mQsNavbarScrim;
protected NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -232,6 +236,8 @@
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
private boolean mNoVisibleNotifications = true;
private ValueAnimator mDarkAnimator;
+ private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private boolean mUserSetupComplete;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -243,6 +249,7 @@
public void setStatusBar(StatusBar bar) {
mStatusBar = bar;
+ mKeyguardBottomArea.setStatusBar(mStatusBar);
}
@Override
@@ -250,7 +257,6 @@
super.onFinishInflate();
mKeyguardStatusBar = findViewById(R.id.keyguard_header);
mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
- mClockView = findViewById(R.id.clock_view);
mNotificationContainerParent = (NotificationsQuickSettingsContainer)
findViewById(R.id.notification_container_parent);
@@ -261,10 +267,10 @@
mNotificationStackScroller.setOnEmptySpaceClickListener(this);
mKeyguardBottomArea = findViewById(R.id.keyguard_bottom_area);
mQsNavbarScrim = findViewById(R.id.qs_navbar_scrim);
- mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
- mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
mLastOrientation = getResources().getConfiguration().orientation;
+ initBottomArea();
+
mQsFrame = findViewById(R.id.qs_frame);
}
@@ -324,6 +330,38 @@
}
}
+ public void onOverlayChanged() {
+ // Re-inflate the status view group.
+ int index = indexOfChild(mKeyguardStatusView);
+ removeView(mKeyguardStatusView);
+ mKeyguardStatusView = (KeyguardStatusView) LayoutInflater.from(mContext).inflate(
+ R.layout.keyguard_status_view,
+ this,
+ false);
+ addView(mKeyguardStatusView, index);
+
+ // Update keyguard bottom area
+ index = indexOfChild(mKeyguardBottomArea);
+ removeView(mKeyguardBottomArea);
+ mKeyguardBottomArea = (KeyguardBottomAreaView) LayoutInflater.from(mContext).inflate(
+ R.layout.keyguard_bottom_area,
+ this,
+ false);
+ addView(mKeyguardBottomArea, index);
+ initBottomArea();
+ }
+
+ private void initBottomArea() {
+ mAffordanceHelper = new KeyguardAffordanceHelper(this, getContext());
+ mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
+ mKeyguardBottomArea.setStatusBar(mStatusBar);
+ mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
+ }
+
+ public void setKeyguardIndicationController(KeyguardIndicationController indicationController) {
+ mKeyguardBottomArea.setKeyguardIndicationController(indicationController);
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -331,7 +369,8 @@
// Update Clock Pivot
mKeyguardStatusView.setPivotX(getWidth() / 2);
- mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f * mClockView.getTextSize());
+ mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f *
+ mKeyguardStatusView.getClockTextSize());
// Calculate quick setting heights.
int oldMaxHeight = mQsMaxExpansionHeight;
@@ -2550,7 +2589,7 @@
private void setDarkAmount(float amount) {
mDarkAmount = amount;
- mKeyguardStatusView.setDark(amount == 1);
+ mKeyguardStatusView.setDark(mDarkAmount);
positionClockAndNotifications();
}
@@ -2571,4 +2610,31 @@
mStatusBar.updateKeyguardMaxNotifications();
}
}
+
+ public void refreshTime() {
+ mKeyguardStatusView.refreshTime();
+ }
+
+ public void setStatusAccessibilityImportance(int mode) {
+ mKeyguardStatusView.setImportantForAccessibility(mode);
+ }
+
+ /**
+ * TODO: this should be removed.
+ * It's not correct to pass this view forward because other classes will end up adding
+ * children to it. Theme will be out of sync.
+ * @return bottom area view
+ */
+ public KeyguardBottomAreaView getKeyguardBottomAreaView() {
+ return mKeyguardBottomArea;
+ }
+
+ public void setUserSetupComplete(boolean userSetupComplete) {
+ mUserSetupComplete = userSetupComplete;
+ mKeyguardBottomArea.setUserSetupComplete(userSetupComplete);
+ }
+
+ public LockIcon getLockIcon() {
+ return mKeyguardBottomArea.getLockIcon();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 9cb4488..b970b1b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -56,6 +56,7 @@
private long mDownTime;
private float mMinExpandHeight;
private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
+ private boolean mPanelUpdateWhenAnimatorEnds;
private final void logf(String fmt, Object... args) {
Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -508,7 +509,7 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- if (mInstantExpanding || !mNotificationsDragEnabled
+ if (mInstantExpanding || !mNotificationsDragEnabled || mTouchDisabled
|| (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) {
return false;
}
@@ -759,14 +760,14 @@
if (clearAllExpandHack && !mCancelled) {
setExpandedHeightInternal(getMaxPanelHeight());
}
- mHeightAnimator = null;
+ setAnimator(null);
if (!mCancelled) {
notifyExpandingFinished();
}
notifyBarPanelExpansionChanged();
}
});
- mHeightAnimator = animator;
+ setAnimator(animator);
animator.start();
}
@@ -803,15 +804,28 @@
protected void requestPanelHeightUpdate() {
float currentMaxPanelHeight = getMaxPanelHeight();
- // If the user isn't actively poking us, let's update the height
- if ((!mTracking || isTrackingBlocked())
- && mHeightAnimator == null
- && !isFullyCollapsed()
- && currentMaxPanelHeight != mExpandedHeight
- && mPeekAnimator == null
- && !mPeekTouching) {
- setExpandedHeight(currentMaxPanelHeight);
+ if (isFullyCollapsed()) {
+ return;
}
+
+ if (currentMaxPanelHeight == mExpandedHeight) {
+ return;
+ }
+
+ if (mPeekAnimator != null || mPeekTouching) {
+ return;
+ }
+
+ if (mTracking && !isTrackingBlocked()) {
+ return;
+ }
+
+ if (mHeightAnimator != null) {
+ mPanelUpdateWhenAnimatorEnds = true;
+ return;
+ }
+
+ setExpandedHeight(currentMaxPanelHeight);
}
public void setExpandedHeightInternal(float h) {
@@ -1063,7 +1077,7 @@
@Override
public void onAnimationEnd(Animator animation) {
if (mCancelled) {
- mHeightAnimator = null;
+ setAnimator(null);
onAnimationFinished.run();
} else {
startUnlockHintAnimationPhase2(onAnimationFinished);
@@ -1071,7 +1085,7 @@
}
});
animator.start();
- mHeightAnimator = animator;
+ setAnimator(animator);
View[] viewsToAnimate = {
mKeyguardBottomArea.getIndicationArea(),
@@ -1093,6 +1107,14 @@
}
}
+ private void setAnimator(ValueAnimator animator) {
+ mHeightAnimator = animator;
+ if (animator == null && mPanelUpdateWhenAnimatorEnds) {
+ mPanelUpdateWhenAnimatorEnds = false;
+ requestPanelHeightUpdate();
+ }
+ }
+
/**
* Phase 2: Bounce down.
*/
@@ -1103,13 +1125,13 @@
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mHeightAnimator = null;
+ setAnimator(null);
onAnimationFinished.run();
notifyBarPanelExpansionChanged();
}
});
animator.start();
- mHeightAnimator = animator;
+ setAnimator(animator);
}
private ValueAnimator createHeightAnimator(float targetHeight) {
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 8cd8791..7633767 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -31,7 +31,6 @@
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.LayoutDirection;
-import android.util.Log;
import com.android.settingslib.R;
import com.android.settingslib.Utils;
@@ -82,6 +81,22 @@
{-1.9f / VIEWPORT, -1.9f / VIEWPORT},
};
+ // Rounded corners are achieved by arcing a circle of radius `mCornerRadius` from its tangent
+ // points along the curve. On the top and left corners of the triangle, the tangents are as
+ // follows:
+ // 1) Along the straight lines (y = 0 and x = width):
+ // Ps = R / tan(45)
+ // 2) Along the diagonal line (y = x):
+ // Pd = √((Ps^2) / 2)
+ //
+ // I.e., the points where we stop the straight lines lie at (starting drawing from the bottom-
+ // right corner and counter-clockwise): (width, height - Radius), (width, Ps), (width - Pd, Pd),
+ // (Pd, height - Pd), (Ps, height), and finally (width - Radius, height).
+ private static final double TAN_THETA = Math.tan(Math.PI / 8.f);
+ private final float mCornerRadius;
+ private final float mCircleOffsetStraight;
+ private final float mCircleOffsetDiag;
+
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final int mDarkModeBackgroundColor;
@@ -113,6 +128,11 @@
mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
mHandler = new Handler();
setDarkIntensity(0);
+
+ mCornerRadius = context.getResources()
+ .getDimensionPixelSize(R.dimen.stat_sys_mobile_signal_corner_radius);
+ mCircleOffsetStraight = mCornerRadius / (float) TAN_THETA;
+ mCircleOffsetDiag = (float) Math.sqrt(Math.pow(mCircleOffsetStraight, 2.f) / 2.f);
}
@Override
@@ -204,11 +224,40 @@
mFullPath.setFillType(FillType.WINDING);
float width = getBounds().width();
float height = getBounds().height();
- float padding = (PAD * width);
- mFullPath.moveTo(width - padding, height - padding);
- mFullPath.lineTo(width - padding, padding);
- mFullPath.lineTo(padding, height - padding);
- mFullPath.lineTo(width - padding, height - padding);
+ float padding = (int) (PAD * width); // Stay on pixel boundary
+
+ // 1 - Bottom right, above corner
+ mFullPath.moveTo(width - padding, height - padding - mCornerRadius);
+ // 2 - Line to top right, below corner
+ mFullPath.lineTo(width - padding, padding + mCircleOffsetStraight);
+ // 3 - Arc to top right, on hypotenuse
+ mFullPath.arcTo(
+ width - padding - (2 * mCornerRadius),
+ padding + mCircleOffsetStraight - mCornerRadius,
+ width - padding,
+ padding + mCircleOffsetStraight + mCornerRadius,
+ 0.f, -135.f, false
+ );
+ // 4 - Line to bottom left, on hypotenuse
+ mFullPath.lineTo(padding + mCircleOffsetDiag, height - padding - mCircleOffsetDiag);
+ // 5 - Arc to bottom left, on leg
+ mFullPath.arcTo(
+ padding + mCircleOffsetStraight - mCornerRadius,
+ height - padding - (2 * mCornerRadius),
+ padding + mCircleOffsetStraight + mCornerRadius,
+ height - padding,
+ -135.f, -135.f, false
+ );
+ // 6 - Line to bottom rght, before corner
+ mFullPath.lineTo(width - padding - mCornerRadius, height - padding);
+ // 7 - Arc to beginning (bottom right, above corner)
+ mFullPath.arcTo(
+ width - padding - (2 * mCornerRadius),
+ height - padding - (2 * mCornerRadius),
+ width - padding,
+ height - padding,
+ 90.f, -90.f, false
+ );
if (mState == STATE_CARRIER_CHANGE) {
float cutWidth = (DOT_CUT_WIDTH * 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 8ce86ff..7564c82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -49,6 +49,7 @@
import android.app.RemoteInput;
import android.app.StatusBarManager;
import android.app.TaskStackBuilder;
+import android.app.WallpaperManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
@@ -57,6 +58,8 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -150,7 +153,6 @@
import com.android.internal.util.NotificationMessagingUtil;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView.OnDismissAction;
-import com.android.keyguard.KeyguardStatusView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
@@ -243,6 +245,8 @@
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.volume.VolumeComponent;
+import com.google.android.colorextraction.ColorExtractor;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -262,7 +266,8 @@
OnHeadsUpChangedListener, VisualStabilityManager.Callback, CommandQueue.Callbacks,
ActivatableNotificationView.OnActivatedListener,
ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
- ExpandableNotificationRow.OnExpandClickListener, InflationCallback {
+ ExpandableNotificationRow.OnExpandClickListener, InflationCallback,
+ ColorExtractor.OnColorsChangedListener {
public static final boolean MULTIUSER_DEBUG = false;
public static final boolean ENABLE_REMOTE_INPUT =
@@ -300,7 +305,7 @@
private static final String NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION
= "com.android.systemui.statusbar.work_challenge_unlocked_notification_action";
public static final String TAG = "StatusBar";
- public static final boolean DEBUG = false;
+ public static final boolean DEBUG = true;
public static final boolean SPEW = false;
public static final boolean DUMPTRUCK = true; // extra dumpsys info
public static final boolean DEBUG_GESTURES = false;
@@ -426,6 +431,7 @@
Object mQueueLock = new Object();
protected StatusBarIconController mIconController;
+ private IconManager mIconManager;
// expanded notifications
protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -444,8 +450,6 @@
// top bar
protected KeyguardStatusBarView mKeyguardStatusBar;
- KeyguardStatusView mKeyguardStatusView;
- KeyguardBottomAreaView mKeyguardBottomArea;
boolean mLeaveOpenOnKeyguardHide;
KeyguardIndicationController mKeyguardIndicationController;
@@ -512,8 +516,8 @@
mUserSetup = userSetup;
if (!mUserSetup && mStatusBarView != null)
animateCollapseQuickSettings();
- if (mKeyguardBottomArea != null) {
- mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
+ if (mNotificationPanel != null) {
+ mNotificationPanel.setUserSetupComplete(mUserSetup);
}
updateQsExpansionEnabled();
}
@@ -722,6 +726,7 @@
private KeyguardMonitorImpl mKeyguardMonitor;
private BatteryController mBatteryController;
protected boolean mPanelExpanded;
+ private IOverlayManager mOverlayManager;
private boolean mKeyguardRequested;
private boolean mIsKeyguard;
private LogMaker mStatusBarStateLog;
@@ -732,6 +737,7 @@
private HashMap<String, Entry> mPendingNotifications = new HashMap<>();
private boolean mClearAllEnabled;
@Nullable private View mAmbientIndicationContainer;
+ private ColorExtractor mColorExtractor;
private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
final int N = array.size();
@@ -774,6 +780,11 @@
mAssistManager = Dependency.get(AssistManager.class);
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
mSystemServicesProxy = SystemServicesProxy.getInstance(mContext);
+ mOverlayManager = IOverlayManager.Stub.asInterface(
+ ServiceManager.getService(Context.OVERLAY_SERVICE));
+
+ mColorExtractor = Dependency.get(ColorExtractor.class);
+ mColorExtractor.addOnColorsChangedListener(this);
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mDisplay = mWindowManager.getDefaultDisplay();
@@ -970,8 +981,16 @@
public void onDensityOrFontScaleChanged() {
StatusBar.this.onDensityOrFontScaleChanged();
}
+
+ @Override
+ public void onOverlayChanged() {
+ StatusBar.this.onOverlayChanged();
+ }
};
Dependency.get(ConfigurationController.class).addCallback(mConfigurationListener);
+
+ // Make sure that we're using the correct theme
+ onOverlayChanged();
}
protected void createIconController() {
@@ -1020,8 +1039,8 @@
.replace(R.id.status_bar_container, new CollapsedStatusBarFragment(),
CollapsedStatusBarFragment.TAG)
.commit();
- Dependency.get(StatusBarIconController.class).addIconGroup(
- new IconManager((ViewGroup) mKeyguardStatusBar.findViewById(R.id.statusIcons)));
+ mIconManager = new IconManager(mKeyguardStatusBar.findViewById(R.id.statusIcons));
+ Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
mIconController = Dependency.get(StatusBarIconController.class);
mHeadsUpManager = new HeadsUpManager(context, mStatusBarWindow, mGroupManager);
@@ -1073,15 +1092,12 @@
mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
}
- mKeyguardStatusView =
- (KeyguardStatusView) mStatusBarWindow.findViewById(R.id.keyguard_status_view);
- mKeyguardBottomArea =
- (KeyguardBottomAreaView) mStatusBarWindow.findViewById(R.id.keyguard_bottom_area);
mKeyguardIndicationController =
SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
(ViewGroup) mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
- mKeyguardBottomArea.getLockIcon());
- mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
+ mNotificationPanel.getLockIcon());
+ mNotificationPanel.setKeyguardIndicationController(mKeyguardIndicationController);
+
mAmbientIndicationContainer = mStatusBarWindow.findViewById(
R.id.ambient_indication_container);
@@ -1134,8 +1150,7 @@
// Other icons
mVolumeComponent = getComponent(VolumeComponent.class);
- mKeyguardBottomArea.setStatusBar(this);
- mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
+ mNotificationPanel.setUserSetupComplete(mUserSetup);
if (UserManager.get(mContext).isUserSwitcherEnabled()) {
createUserSwitcher();
}
@@ -1285,12 +1300,6 @@
if (mBrightnessMirrorController != null) {
mBrightnessMirrorController.onDensityOrFontScaleChanged();
}
- inflateSignalClusters();
- mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
- inflateDismissView();
- updateClearAll();
- inflateEmptyShadeView();
- updateEmptyShadeView();
mStatusBarKeyguardViewManager.onDensityOrFontScaleChanged();
// TODO: Bring these out of StatusBar.
((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
@@ -1299,6 +1308,44 @@
if (mKeyguardUserSwitcher != null) {
mKeyguardUserSwitcher.onDensityOrFontScaleChanged();
}
+ mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
+
+ reevaluateStyles();
+ }
+
+ protected void onOverlayChanged() {
+ final boolean usingDarkTheme = isUsingDarkTheme();
+ if (DEBUG) {
+ Log.d(TAG, "Updating theme because overlay changed. Is theme dark? " + usingDarkTheme);
+ }
+ reevaluateStyles();
+
+ // Clock and bottom icons
+ mNotificationPanel.onOverlayChanged();
+
+ // Recreate Indication controller because internal references changed
+ // TODO: unregister callbacks before recreating
+ mKeyguardIndicationController =
+ SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
+ mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
+ mNotificationPanel.getLockIcon());
+ mNotificationPanel.setKeyguardIndicationController(mKeyguardIndicationController);
+ mKeyguardIndicationController
+ .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+ mKeyguardIndicationController.setVisible(mState == StatusBarState.KEYGUARD);
+ mKeyguardIndicationController.setDozing(mDozing);
+
+ // Top status bar with system icons and clock
+ mKeyguardStatusBar.onOverlayChanged();
+ mIconManager.onOverlayChanged();
+ }
+
+ protected void reevaluateStyles() {
+ inflateSignalClusters();
+ inflateDismissView();
+ updateClearAll();
+ inflateEmptyShadeView();
+ updateEmptyShadeView();
}
private void updateNotificationsOnDensityOrFontScaleChanged() {
@@ -1347,20 +1394,20 @@
}
private void inflateEmptyShadeView() {
+ if (mStackScroller == null) {
+ return;
+ }
mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_no_notifications, mStackScroller, false);
mStackScroller.setEmptyShadeView(mEmptyShadeView);
}
private void inflateDismissView() {
- if (!mClearAllEnabled) {
+ if (!mClearAllEnabled || mStackScroller == null) {
return;
}
- // Always inflate with a dark theme, since this sits on the scrim.
- ContextThemeWrapper themedContext = new ContextThemeWrapper(mContext,
- style.Theme_DeviceDefault);
- mDismissView = (DismissView) LayoutInflater.from(themedContext).inflate(
+ mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
mDismissView.setOnButtonClickListener(new View.OnClickListener() {
@Override
@@ -1476,10 +1523,8 @@
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
getBouncerContainer(), mScrimController,
mFingerprintUnlockController);
- mKeyguardIndicationController.setStatusBarKeyguardViewManager(
- mStatusBarKeyguardViewManager);
- mKeyguardIndicationController.setUserInfoController(
- Dependency.get(UserInfoController.class));
+ mKeyguardIndicationController
+ .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mFingerprintUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mRemoteInputController.addCallback(mStatusBarKeyguardViewManager);
@@ -2589,7 +2634,7 @@
public void setQsExpanded(boolean expanded) {
mStatusBarWindowManager.setQsExpanded(expanded);
- mKeyguardStatusView.setImportantForAccessibility(expanded
+ mNotificationPanel.setStatusAccessibilityImportance(expanded
? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
: View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
}
@@ -2783,8 +2828,20 @@
return mNotificationPanel.hideStatusBarIconsWhenExpanded();
}
- public KeyguardIndicationController getKeyguardIndicationController() {
- return mKeyguardIndicationController;
+ @Override
+ public void onColorsChanged(ColorExtractor.GradientColors colors, int which) {
+ updateTheme();
+ }
+
+ public boolean isUsingDarkTheme() {
+ OverlayInfo themeInfo = null;
+ try {
+ themeInfo = mOverlayManager.getOverlayInfo("com.android.systemui.theme.dark",
+ mCurrentUserId);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ return themeInfo != null && themeInfo.isEnabled();
}
@Nullable
@@ -4426,6 +4483,7 @@
mScrimController.setKeyguardShowing(false);
}
mNotificationPanel.setBarState(mState, mKeyguardFadingAway, goingToFullShade);
+ updateTheme();
updateDozingState();
updatePublicMode();
updateStackScrollerState(goingToFullShade, fromShadeLocked);
@@ -4438,6 +4496,35 @@
Trace.endSection();
}
+ /**
+ * Switches theme from light to dark and vice-versa.
+ */
+ private void updateTheme() {
+ boolean useDarkTheme;
+ if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
+ useDarkTheme = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK)
+ .supportsDarkText();
+ } else {
+ useDarkTheme = mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM)
+ .supportsDarkText();
+ }
+
+ // Enable/Disable dark overlay
+ if (isUsingDarkTheme() != useDarkTheme) {
+ if (DEBUG) {
+ Log.d(TAG, "Switching theme to: " + (useDarkTheme ? "Dark" : "Light"));
+ }
+ try {
+ mOverlayManager.setEnabled("com.android.systemui.theme.dark",
+ useDarkTheme, mCurrentUserId);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Can't change theme", e);
+ return;
+ }
+ mStatusBarWindowManager.setKeyguardDark(useDarkTheme);
+ }
+ }
+
private void updateDozingState() {
Trace.beginSection("StatusBar#updateDozingState");
boolean animate = !mDozing && mDozeServiceHost.shouldAnimateWakeup();
@@ -4585,6 +4672,7 @@
mStackScroller.setStatusBarState(state);
updateReportRejectedTouchVisibility();
updateDozing();
+ updateTheme();
mNotificationShelf.setStatusBarState(state);
}
@@ -4665,8 +4753,12 @@
return mNavigationBarView;
}
+ /**
+ * TODO: Remove this method. Views should not be passed forward. Will cause theme issues.
+ * @return bottom area view
+ */
public KeyguardBottomAreaView getKeyguardBottomAreaView() {
- return mKeyguardBottomArea;
+ return mNotificationPanel.getKeyguardBottomAreaView();
}
// ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
@@ -5020,7 +5112,6 @@
where.getLocationInWindow(mTmpInt2);
mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
mTmpInt2[1] + where.getHeight() / 2);
- mNotificationPanel.setTouchDisabled(false);
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
mFalsingManager.onScreenOnFromTouch();
}
@@ -5177,7 +5268,7 @@
@Override
public void dozeTimeTick() {
- mKeyguardStatusView.refreshTime();
+ mNotificationPanel.refreshTime();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index a3ef91d..64b21b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -14,7 +14,10 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.ColorInt;
import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -26,6 +29,7 @@
import android.widget.LinearLayout.LayoutParams;
import com.android.internal.statusbar.StatusBarIcon;
+import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.StatusBarIconView;
@@ -57,7 +61,6 @@
return ret;
}
-
/**
* Version of ViewGroup that observers state from the DarkIconDispatcher.
*/
@@ -165,6 +168,17 @@
}
}
+ protected void onOverlayChanged() {
+ @ColorInt int iconColor = Utils.getColorAttr(mContext, R.attr.bgProtectTextColor);
+ for (int i = 0; i < mGroup.getChildCount(); i++) {
+ View child = mGroup.getChildAt(i);
+ if (child instanceof StatusBarIconView) {
+ StatusBarIconView icon = (StatusBarIconView) child;
+ icon.setStaticDrawableColor(iconColor);
+ }
+ }
+ }
+
private void setHeightAndCenter(ImageView imageView, int height) {
ViewGroup.LayoutParams params = imageView.getLayoutParams();
params.height = height;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 0326e40..93dc6de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -111,6 +111,18 @@
mLpChanged.copyFrom(mLp);
}
+ public void setKeyguardDark(boolean dark) {
+ int vis = mStatusBarView.getSystemUiVisibility();
+ if (dark) {
+ vis = vis | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+ vis = vis | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+ } else {
+ vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+ vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+ }
+ mStatusBarView.setSystemUiVisibility(vis);
+ }
+
private void applyKeyguardFlags(State state) {
if (state.keyguardShowing) {
mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index f050be4..236e008 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -277,7 +277,7 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (mService.isDozing() && !mService.isPulsing()) {
+ if (mService.isDozing() && !mStackScrollLayout.hasPulsingNotifications()) {
// Capture all touch events in always-on.
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
index 788fda8..418c48e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ConfigurationController.java
@@ -27,5 +27,6 @@
interface ConfigurationListener {
default void onConfigChanged(Configuration newConfig) {}
default void onDensityOrFontScaleChanged() {}
+ default void onOverlayChanged() {}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index dc33633..74a30fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -23,6 +23,7 @@
import android.content.res.TypedArray;
import android.icu.text.DateFormat;
import android.icu.text.DisplayContext;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;
@@ -115,4 +116,15 @@
mLastText = text;
}
}
+
+ public void setDatePattern(String pattern) {
+ if (TextUtils.equals(pattern, mDatePattern)) {
+ return;
+ }
+ mDatePattern = pattern;
+ mDateFormat = null;
+ if (isAttachedToWindow()) {
+ updateClock();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index e409b9c..41ef781 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -59,7 +59,7 @@
private boolean mPanelTracking;
private boolean mExpansionChanging;
private boolean mPanelFullWidth;
- private boolean mPulsing;
+ private boolean mHasPulsingNotifications;
private boolean mUnlockHintRunning;
public AmbientState(Context context) {
@@ -287,12 +287,12 @@
mPanelTracking = panelTracking;
}
- public boolean isPulsing() {
- return mPulsing;
+ public boolean hasPulsingNotifications() {
+ return mHasPulsingNotifications;
}
- public void setPulsing(boolean pulsing) {
- mPulsing = pulsing;
+ public void setHasPulsingNotifications(boolean hasPulsing) {
+ mHasPulsingNotifications = hasPulsing;
}
public boolean isPanelTracking() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 679d119..84acaf1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -54,7 +54,6 @@
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.OverScroller;
@@ -1946,7 +1945,7 @@
int numShownItems = 0;
boolean finish = false;
int maxDisplayedNotifications = mAmbientState.isDark()
- ? (isPulsing() ? 1 : 0)
+ ? (hasPulsingNotifications() ? 1 : 0)
: mMaxDisplayedNotifications;
for (int i = 0; i < getChildCount(); i++) {
@@ -1955,7 +1954,8 @@
&& !expandableView.hasNoContentHeight()) {
boolean limitReached = maxDisplayedNotifications != -1
&& numShownItems >= maxDisplayedNotifications;
- boolean notificationOnAmbientThatIsNotPulsing = isPulsing()
+ boolean notificationOnAmbientThatIsNotPulsing = mAmbientState.isDark()
+ && hasPulsingNotifications()
&& expandableView instanceof ExpandableNotificationRow
&& !isPulsing(((ExpandableNotificationRow) expandableView).getEntry());
if (limitReached || notificationOnAmbientThatIsNotPulsing) {
@@ -2013,7 +2013,7 @@
return false;
}
- private boolean isPulsing() {
+ public boolean hasPulsingNotifications() {
return mPulsing != null;
}
@@ -2225,14 +2225,15 @@
ActivatableNotificationView firstView = mFirstVisibleBackgroundChild;
int top = 0;
if (firstView != null) {
- int finalTranslationY = (int) ViewState.getFinalTranslationY(firstView);
+ // Round Y up to avoid seeing the background during animation
+ int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView));
if (mAnimateNextBackgroundTop
|| mTopAnimator == null && mCurrentBounds.top == finalTranslationY
|| mTopAnimator != null && mEndAnimationRect.top == finalTranslationY) {
// we're ending up at the same location as we are now, lets just skip the animation
top = finalTranslationY;
} else {
- top = (int) firstView.getTranslationY();
+ top = (int) Math.ceil(firstView.getTranslationY());
}
}
ActivatableNotificationView lastView =
@@ -2843,7 +2844,7 @@
}
private void updateNotificationAnimationStates() {
- boolean running = mAnimationsEnabled || isPulsing();
+ boolean running = mAnimationsEnabled || hasPulsingNotifications();
mShelf.setAnimationsEnabled(running);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -2854,7 +2855,7 @@
}
private void updateAnimationState(View child) {
- updateAnimationState((mAnimationsEnabled || isPulsing())
+ updateAnimationState((mAnimationsEnabled || hasPulsingNotifications())
&& (mIsExpanded || isPinnedHeadsUp(child)), child);
}
@@ -4126,7 +4127,7 @@
return;
}
mPulsing = pulsing;
- mAmbientState.setPulsing(isPulsing());
+ mAmbientState.setHasPulsingNotifications(hasPulsingNotifications());
updateNotificationAnimationStates();
updateContentHeight();
notifyHeightChangeListener(mShelf);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 5717600..8235bc7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -416,6 +416,7 @@
if (i == 0 && row.isAboveShelf()) {
// the first hun can't get off screen.
clampHunToMaxTranslation(ambientState, row, childState);
+ childState.hidden = false;
}
}
if (row.isPinned()) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
index 15cebc7..8905d72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiBaseFragmentTest.java
@@ -14,13 +14,18 @@
package com.android.systemui;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
import android.app.Fragment;
+import android.app.Instrumentation;
import android.support.test.InstrumentationRegistry;
import android.testing.BaseFragmentTest;
import com.android.systemui.utils.leaks.LeakCheckedTest;
import com.android.systemui.utils.leaks.LeakCheckedTest.SysuiLeakCheck;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -33,6 +38,7 @@
protected final TestableDependency mDependency = new TestableDependency(mContext);
protected SysuiTestableContext mSysuiContext;
+ private Instrumentation mRealInstrumentation;
public SysuiBaseFragmentTest(Class<? extends Fragment> cls) {
super(cls);
@@ -44,6 +50,20 @@
SystemUIFactory.createFromConfig(mContext);
// TODO: Figure out another way to give reference to a SysuiTestableContext.
mSysuiContext = (SysuiTestableContext) mContext;
+
+ mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
+ Instrumentation inst = spy(mRealInstrumentation);
+ when(inst.getContext()).thenThrow(new RuntimeException(
+ "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
+ when(inst.getTargetContext()).thenThrow(new RuntimeException(
+ "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
+ InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
+ }
+
+ @After
+ public void SysuiTeardown() {
+ InstrumentationRegistry.registerInstance(mRealInstrumentation,
+ InstrumentationRegistry.getArguments());
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 9b67529..361a20f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -15,6 +15,10 @@
*/
package com.android.systemui;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.Instrumentation;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
@@ -24,6 +28,7 @@
import android.testing.LeakCheck;
import android.util.Log;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -42,11 +47,26 @@
public SysuiTestableContext mContext = new SysuiTestableContext(
InstrumentationRegistry.getContext(), getLeakCheck());
public TestableDependency mDependency = new TestableDependency(mContext);
+ private Instrumentation mRealInstrumentation;
@Before
public void SysuiSetup() throws Exception {
System.setProperty("dexmaker.share_classloader", "true");
SystemUIFactory.createFromConfig(mContext);
+
+ mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
+ Instrumentation inst = spy(mRealInstrumentation);
+ when(inst.getContext()).thenThrow(new RuntimeException(
+ "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
+ when(inst.getTargetContext()).thenThrow(new RuntimeException(
+ "SysUI Tests should use SysuiTestCase#getContext or SysuiTestCase#mContext"));
+ InstrumentationRegistry.registerInstance(inst, InstrumentationRegistry.getArguments());
+ }
+
+ @After
+ public void SysuiTeardown() {
+ InstrumentationRegistry.registerInstance(mRealInstrumentation,
+ InstrumentationRegistry.getArguments());
}
protected LeakCheck getLeakCheck() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 6380847..b6827ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -232,6 +232,17 @@
}
@Test
+ public void testBindNotification_UnblockablePackageDoesNotUseChannelName() throws Exception {
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, Collections.singleton(TEST_PACKAGE_NAME));
+ final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
+ assertEquals(mContext.getString(R.string.notification_header_default_channel),
+ textView.getText());
+ }
+
+ @Test
public void testBindNotification_DefaultChannelUsesNameWhenMoreThanOneChannelExists()
throws Exception {
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
@@ -332,6 +343,21 @@
}
@Test
+ public void testBindNotification_SettingsTextWithMultipleChannelsForUnblockableApp()
+ throws Exception {
+ when(mMockINotificationManager.getNumNotificationChannelsForPackage(
+ eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(2);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn,
+ (View v, NotificationChannel c, int appUid) -> {
+ }, null, null, null, Collections.singleton(TEST_PACKAGE_NAME));
+ final TextView settingsButton =
+ (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+ assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
+ }
+
+ @Test
public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
@@ -502,6 +528,19 @@
}
@Test
+ public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception {
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+ mNotificationChannel.getImportance(), mSbn, null, null, null,
+ null, Collections.singleton(TEST_PACKAGE_NAME));
+ final TextView numChannelsView =
+ (TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
+ assertEquals(View.VISIBLE, numChannelsView.getVisibility());
+ assertEquals(mContext.getString(R.string.notification_unblockable_desc),
+ numChannelsView.getText());
+ }
+
+ @Test
@UiThreadTest
public void testBindNotification_ChannelDisabledTextShowsForDefaultChannel()
throws Exception {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SignalClusterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SignalClusterViewTest.java
new file mode 100644
index 0000000..28a5aa3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SignalClusterViewTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.support.test.filters.SmallTest;
+import android.telephony.SubscriptionInfo;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.LayoutInflater;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+@SmallTest
+public class SignalClusterViewTest extends SysuiTestCase {
+
+ private SignalClusterView mSignalCluster;
+
+ @Before
+ public void setup() {
+ mSignalCluster = (SignalClusterView) LayoutInflater.from(mContext)
+ .inflate(R.layout.signal_cluster_view, null);
+ }
+
+ @Test
+ public void testNonDefaultSim() {
+ SubscriptionInfo first = mock(SubscriptionInfo.class);
+ SubscriptionInfo second = mock(SubscriptionInfo.class);
+ when(first.getSubscriptionId()).thenReturn(0);
+ when(second.getSubscriptionId()).thenReturn(1);
+ mSignalCluster.setSubs(Arrays.asList(first, second));
+ mSignalCluster.setQsSignalCluster();
+ mSignalCluster.setMobileDataIndicators(new IconState(true, 0, 0, ""), null, 0, 0,
+ false, false, "", "", false, 1, false);
+ }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
index 9b7c597..d925364 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/WakeLockTest.java
@@ -41,9 +41,7 @@
@Before
public void setUp() {
- Context context = InstrumentationRegistry.getContext();
-
- mInner = WakeLock.createPartialInner(context, WakeLockTest.class.getName());
+ mInner = WakeLock.createPartialInner(mContext, WakeLockTest.class.getName());
mWakeLock = WakeLock.wrap(mInner);
}
diff --git a/packages/SysuiDarkThemeOverlay/Android.mk b/packages/SysuiDarkThemeOverlay/Android.mk
new file mode 100644
index 0000000..4b83058
--- /dev/null
+++ b/packages/SysuiDarkThemeOverlay/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := SysuiDarkTheme
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := SysuiDarkThemeOverlay
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/SysuiDarkThemeOverlay/AndroidManifest.xml b/packages/SysuiDarkThemeOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..ba1c91c
--- /dev/null
+++ b/packages/SysuiDarkThemeOverlay/AndroidManifest.xml
@@ -0,0 +1,8 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.systemui.theme.dark"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android" android:priority="1"/>
+
+ <application android:label="@string/sysui_overlay_dark" android:hasCode="false"/>
+</manifest>
diff --git a/packages/SysuiDarkThemeOverlay/res/values/strings.xml b/packages/SysuiDarkThemeOverlay/res/values/strings.xml
new file mode 100644
index 0000000..71f48d6
--- /dev/null
+++ b/packages/SysuiDarkThemeOverlay/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <string name="sysui_overlay_dark">Dark</string>
+
+</resources>
+
diff --git a/packages/SysuiDarkThemeOverlay/res/values/themes_device_defaults.xml b/packages/SysuiDarkThemeOverlay/res/values/themes_device_defaults.xml
new file mode 100644
index 0000000..28ecfa0
--- /dev/null
+++ b/packages/SysuiDarkThemeOverlay/res/values/themes_device_defaults.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- Dark theme for a window that should look like the Settings app. -->
+ <style name="Theme.DeviceDefault.QuickSettings" parent="android:Theme.DeviceDefault">
+ <!-- Color palette -->
+ <item name="android:colorPrimary">@*android:color/primary_device_default_settings</item>
+ <item name="android:colorPrimaryDark">@*android:color/primary_dark_device_default_settings</item>
+ <item name="android:textColorPrimaryInverse">@*android:color/primary_text_material_light</item>
+ <item name="android:textColorSecondaryInverse">@*android:color/secondary_text_material_light</item>
+ <item name="android:colorSecondary">@*android:color/secondary_device_default_settings</item>
+ <item name="android:colorAccent">@*android:color/accent_device_default_dark</item>
+ <item name="android:colorControlNormal">?android:attr/textColorPrimary</item>
+ <item name="android:colorBackgroundFloating">#000</item>
+ </style>
+</resources>
\ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index ddc9e6c..96f1d64 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3962,6 +3962,16 @@
// OS: O
APP_TRANSITION_BIND_APPLICATION_DELAY_MS = 945;
+ // FIELD - The group ID of a notification.
+ // Type: string
+ // OS: O
+ FIELD_NOTIFICATION_GROUP_ID = 946;
+
+ // FIELD - If the notification is a group summary: 1.
+ // Type: int encoded boolean
+ // OS: O
+ FIELD_NOTIFICATION_GROUP_SUMMARY = 947;
+
// ---- End O Constants, all O constants go above this line ----
// OPEN: Settings > System > Languages & input > Advanced > Lift to open camera
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e5c3106..5a7f6e3 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -352,7 +352,7 @@
AudioSystem.STREAM_MUSIC, // STREAM_TTS
AudioSystem.STREAM_MUSIC // STREAM_ACCESSIBILITY
};
- private int[] mStreamVolumeAlias;
+ protected static int[] mStreamVolumeAlias;
/**
* Map AudioSystem.STREAM_* constants to app ops. This should be used
@@ -1817,7 +1817,7 @@
}
// UI update and Broadcast Intent
- private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
+ protected void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
streamType = mStreamVolumeAlias[streamType];
if (streamType == AudioSystem.STREAM_MUSIC) {
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 9767e72..78184fa 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -18,7 +18,13 @@
import static android.hardware.usb.UsbManager.USB_CONNECTED;
import static android.hardware.usb.UsbManager.USB_FUNCTION_RNDIS;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
+import static android.net.wifi.WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR;
+import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
+import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
+import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static com.android.server.ConnectivityService.SHORT_ARG;
@@ -805,48 +811,80 @@
}
private void handleWifiApAction(Intent intent) {
- final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
+ final int curState = intent.getIntExtra(EXTRA_WIFI_AP_STATE, WIFI_AP_STATE_DISABLED);
+ final String ifname = intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
+ final int ipmode = intent.getIntExtra(EXTRA_WIFI_AP_MODE, IFACE_IP_MODE_UNSPECIFIED);
+
synchronized (Tethering.this.mPublicSync) {
switch (curState) {
case WifiManager.WIFI_AP_STATE_ENABLING:
// We can see this state on the way to both enabled and failure states.
break;
case WifiManager.WIFI_AP_STATE_ENABLED:
- // When the AP comes up and we've been requested to tether it, do so.
- // Otherwise, assume it's a local-only hotspot request.
- final int state = mWifiTetherRequested
- ? IControlsTethering.STATE_TETHERED
- : IControlsTethering.STATE_LOCAL_ONLY;
- tetherMatchingInterfaces(state, ConnectivityManager.TETHERING_WIFI);
+ enableWifiIpServingLocked(ifname, ipmode);
break;
case WifiManager.WIFI_AP_STATE_DISABLED:
case WifiManager.WIFI_AP_STATE_DISABLING:
case WifiManager.WIFI_AP_STATE_FAILED:
default:
- if (DBG) {
- Log.d(TAG, "Canceling WiFi tethering request - AP_STATE=" +
- curState);
- }
- // Tell appropriate interface state machines that they should tear
- // themselves down.
- for (int i = 0; i < mTetherStates.size(); i++) {
- TetherInterfaceStateMachine tism =
- mTetherStates.valueAt(i).stateMachine;
- if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
- tism.sendMessage(
- TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
- break; // There should be at most one of these.
- }
- }
- // Regardless of whether we requested this transition, the AP has gone
- // down. Don't try to tether again unless we're requested to do so.
- mWifiTetherRequested = false;
- break;
+ disableWifiIpServingLocked(curState);
+ break;
}
}
}
}
+ // TODO: Pass in the interface name and, if non-empty, only turn down IP
+ // serving on that one interface.
+ private void disableWifiIpServingLocked(int apState) {
+ if (DBG) Log.d(TAG, "Canceling WiFi tethering request - AP_STATE=" + apState);
+
+ // Tell appropriate interface state machines that they should tear
+ // themselves down.
+ for (int i = 0; i < mTetherStates.size(); i++) {
+ TetherInterfaceStateMachine tism = mTetherStates.valueAt(i).stateMachine;
+ if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
+ tism.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
+ break; // There should be at most one of these.
+ }
+ }
+ // Regardless of whether we requested this transition, the AP has gone
+ // down. Don't try to tether again unless we're requested to do so.
+ mWifiTetherRequested = false;
+ }
+
+ private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
+ // Map wifiIpMode values to IControlsTethering serving states, inferring
+ // from mWifiTetherRequested as a final "best guess".
+ final int ipServingMode;
+ switch (wifiIpMode) {
+ case IFACE_IP_MODE_TETHERED:
+ ipServingMode = IControlsTethering.STATE_TETHERED;
+ break;
+ case IFACE_IP_MODE_LOCAL_ONLY:
+ ipServingMode = IControlsTethering.STATE_LOCAL_ONLY;
+ break;
+ default:
+ // Resort to legacy "guessing" behaviour.
+ //
+ // When the AP comes up and we've been requested to tether it,
+ // do so. Otherwise, assume it's a local-only hotspot request.
+ //
+ // TODO: Once all AP broadcasts are known to include ifname and
+ // mode information delete this code path and log an error.
+ ipServingMode = mWifiTetherRequested
+ ? IControlsTethering.STATE_TETHERED
+ : IControlsTethering.STATE_LOCAL_ONLY;
+ break;
+ }
+
+ if (!TextUtils.isEmpty(ifname)) {
+ changeInterfaceState(ifname, ipServingMode);
+ } else {
+ tetherMatchingInterfaces(ipServingMode, ConnectivityManager.TETHERING_WIFI);
+ }
+ }
+
// TODO: Consider renaming to something more accurate in its description.
// This method:
// - allows requesting either tethering or local hotspot serving states
@@ -879,22 +917,26 @@
return;
}
+ changeInterfaceState(chosenIface, requestedState);
+ }
+
+ private void changeInterfaceState(String ifname, int requestedState) {
final int result;
switch (requestedState) {
case IControlsTethering.STATE_UNAVAILABLE:
case IControlsTethering.STATE_AVAILABLE:
- result = untether(chosenIface);
+ result = untether(ifname);
break;
case IControlsTethering.STATE_TETHERED:
case IControlsTethering.STATE_LOCAL_ONLY:
- result = tether(chosenIface, requestedState);
+ result = tether(ifname, requestedState);
break;
default:
Log.wtf(TAG, "Unknown interface state: " + requestedState);
return;
}
if (result != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
- Log.e(TAG, "unable start or stop tethering on iface " + chosenIface);
+ Log.e(TAG, "unable start or stop tethering on iface " + ifname);
return;
}
}
@@ -1377,10 +1419,10 @@
final String iface = who.interfaceName();
switch (mode) {
case IControlsTethering.STATE_TETHERED:
- mgr.updateInterfaceIpState(iface, WifiManager.IFACE_IP_MODE_TETHERED);
+ mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_TETHERED);
break;
case IControlsTethering.STATE_LOCAL_ONLY:
- mgr.updateInterfaceIpState(iface, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ mgr.updateInterfaceIpState(iface, IFACE_IP_MODE_LOCAL_ONLY);
break;
default:
Log.wtf(TAG, "Unknown active serving mode: " + mode);
@@ -1398,7 +1440,7 @@
if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
if (who.lastError() != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
getWifiManager().updateInterfaceIpState(
- who.interfaceName(), WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
+ who.interfaceName(), IFACE_IP_MODE_CONFIGURATION_ERROR);
}
}
}
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index 6902b1a..ffee99f 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -21,6 +21,7 @@
import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.util.MathUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -48,6 +49,10 @@
*/
public static final int LEVEL_COLOR_MATRIX_INVERT_COLOR = 300;
+ private static final int SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX = 1015;
+ private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014;
+ private static final int SURFACE_FLINGER_TRANSACTION_SATURATION = 1022;
+
/**
* Map of level -> color transformation matrix.
*/
@@ -66,6 +71,10 @@
@GuardedBy("mDaltonizerModeLock")
private int mDaltonizerMode = -1;
+ private final Object mSaturationLock = new Object();
+ @GuardedBy("mSaturationLock")
+ private float mSaturation = 1.0f;
+
/* package */ DisplayTransformManager() {
}
@@ -156,6 +165,30 @@
}
/**
+ * Returns the current saturation.
+ */
+ public float getSaturation() {
+ synchronized (mSaturationLock) {
+ return mSaturation;
+ }
+ }
+
+ /**
+ * Sets the saturation level of the display. The default value is 1.0.
+ *
+ * @param saturation A value between 0 (0% saturation, grayscale) and 2 (100% extra saturation)
+ */
+ public void setSaturation(float saturation) {
+ synchronized (mSaturationLock) {
+ saturation = MathUtils.constrain(saturation, 0.0f, 2.0f);
+ if (mSaturation != saturation) {
+ mSaturation = saturation;
+ applySaturation(saturation);
+ }
+ }
+ }
+
+ /**
* Propagates the provided color transformation matrix to the SurfaceFlinger.
*/
private static void applyColorMatrix(float[] m) {
@@ -172,7 +205,7 @@
data.writeInt(0);
}
try {
- flinger.transact(1015, data, null, 0);
+ flinger.transact(SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX, data, null, 0);
} catch (RemoteException ex) {
Slog.e(TAG, "Failed to set color transform", ex);
} finally {
@@ -191,7 +224,7 @@
data.writeInterfaceToken("android.ui.ISurfaceComposer");
data.writeInt(mode);
try {
- flinger.transact(1014, data, null, 0);
+ flinger.transact(SURFACE_FLINGER_TRANSACTION_DALTONIZER, data, null, 0);
} catch (RemoteException ex) {
Slog.e(TAG, "Failed to set Daltonizer mode", ex);
} finally {
@@ -199,4 +232,23 @@
}
}
}
+
+ /**
+ * Propagates the provided saturation to the SurfaceFlinger.
+ */
+ private static void applySaturation(float saturation) {
+ final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+ if (flinger != null) {
+ final Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ data.writeFloat(saturation);
+ try {
+ flinger.transact(SURFACE_FLINGER_TRANSACTION_SATURATION, data, null, 0);
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "Failed to set saturation", ex);
+ } finally {
+ data.recycle();
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index d574265..b3cf57b 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -285,12 +285,6 @@
if (mIsActivated == null || mIsActivated != activated) {
Slog.i(TAG, activated ? "Turning on night display" : "Turning off night display");
- if (mIsActivated != null) {
- Secure.putLongForUser(getContext().getContentResolver(),
- Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, System.currentTimeMillis(),
- mCurrentUser);
- }
-
mIsActivated = activated;
if (mAutoMode != null) {
@@ -430,19 +424,6 @@
outTemp[10] = blue;
}
- private Calendar getLastActivatedTime() {
- final ContentResolver cr = getContext().getContentResolver();
- final long lastActivatedTimeMillis = Secure.getLongForUser(
- cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1, mCurrentUser);
- if (lastActivatedTimeMillis < 0) {
- return null;
- }
-
- final Calendar lastActivatedTime = Calendar.getInstance();
- lastActivatedTime.setTimeInMillis(lastActivatedTimeMillis);
- return lastActivatedTime;
- }
-
private abstract class AutoMode implements NightDisplayController.Callback {
public abstract void onStart();
@@ -522,7 +503,7 @@
mStartTime = mController.getCustomStartTime();
mEndTime = mController.getCustomEndTime();
- mLastActivatedTime = getLastActivatedTime();
+ mLastActivatedTime = mController.getLastActivatedTime();
// Force an update to initialize state.
updateActivated();
@@ -538,7 +519,7 @@
@Override
public void onActivated(boolean activated) {
- mLastActivatedTime = getLastActivatedTime();
+ mLastActivatedTime = mController.getLastActivatedTime();
updateNextAlarm(activated, Calendar.getInstance());
}
@@ -579,7 +560,7 @@
}
boolean activate = state.isNight();
- final Calendar lastActivatedTime = getLastActivatedTime();
+ final Calendar lastActivatedTime = mController.getLastActivatedTime();
if (lastActivatedTime != null) {
final Calendar now = Calendar.getInstance();
final Calendar sunrise = state.sunrise();
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 321b660..fe2c5bd 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -139,6 +139,7 @@
private static final int PROFILE_KEY_IV_SIZE = 12;
private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
+ private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
// Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
private final Object mSeparateChallengeLock = new Object();
@@ -1977,14 +1978,16 @@
}
long handle = getSyntheticPasswordHandleLocked(userId);
// This is a global setting
- long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
+ long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
+ SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM);
return enabled != 0 && handle != SyntheticPasswordManager.DEFAULT_HANDLE;
}
private boolean shouldMigrateToSyntheticPasswordLocked(int userId) throws RemoteException {
long handle = getSyntheticPasswordHandleLocked(userId);
// This is a global setting
- long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 0, UserHandle.USER_SYSTEM);
+ long enabled = getLong(SYNTHETIC_PASSWORD_ENABLED_KEY,
+ SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT, UserHandle.USER_SYSTEM);
return enabled != 0 && handle == SyntheticPasswordManager.DEFAULT_HANDLE;
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
index d1fb28a..d730c56 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsShellCommand.java
@@ -71,7 +71,7 @@
runClear();
break;
case COMMAND_SP:
- runEnableSp();
+ runChangeSp();
break;
case COMMAND_SET_DISABLED:
runSetDisabled();
@@ -107,10 +107,15 @@
mNew = getNextArg();
}
- private void runEnableSp() {
- if (mNew != null) {
- mLockPatternUtils.enableSyntheticPassword();
- getOutPrintWriter().println("Synthetic password enabled");
+ private void runChangeSp() {
+ if (mNew != null ) {
+ if ("1".equals(mNew)) {
+ mLockPatternUtils.enableSyntheticPassword();
+ getOutPrintWriter().println("Synthetic password enabled");
+ } else if ("0".equals(mNew)) {
+ mLockPatternUtils.disableSyntheticPassword();
+ getOutPrintWriter().println("Synthetic password disabled");
+ }
}
getOutPrintWriter().println(String.format("SP Enabled = %b",
mLockPatternUtils.isSyntheticPasswordEnabled()));
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b630368..41682eb 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1051,7 +1051,8 @@
@VisibleForTesting
void init(Looper looper, IPackageManager packageManager, PackageManager packageManagerClient,
LightsManager lightsManager, NotificationListeners notificationListeners,
- ICompanionDeviceManager companionManager, SnoozeHelper snoozeHelper) {
+ ICompanionDeviceManager companionManager, SnoozeHelper snoozeHelper,
+ NotificationUsageStats usageStats) {
Resources resources = getContext().getResources();
mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
@@ -1074,7 +1075,7 @@
} catch (Resources.NotFoundException e) {
extractorNames = new String[0];
}
- mUsageStats = new NotificationUsageStats(getContext());
+ mUsageStats = usageStats;
mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper());
mRankingHelper = new RankingHelper(getContext(),
getContext().getPackageManager(),
@@ -1243,7 +1244,7 @@
init(Looper.myLooper(), AppGlobals.getPackageManager(), getContext().getPackageManager(),
getLocalService(LightsManager.class), new NotificationListeners(),
- null, snoozeHelper);
+ null, snoozeHelper, new NotificationUsageStats(getContext()));
publishBinderService(Context.NOTIFICATION_SERVICE, mService);
publishLocalService(NotificationManagerInternal.class, mInternalService);
}
@@ -2775,7 +2776,7 @@
if (n == null) {
return;
}
- n.sbn.setOverrideGroupKey(GroupHelper.AUTOGROUP_KEY);
+ n.setOverrideGroupKey(GroupHelper.AUTOGROUP_KEY);
EventLogTags.writeNotificationAutogrouped(key);
}
@@ -2784,7 +2785,7 @@
if (n == null) {
return;
}
- n.sbn.setOverrideGroupKey(null);
+ n.setOverrideGroupKey(null);
EventLogTags.writeNotificationUnautogrouped(key);
}
@@ -3714,7 +3715,7 @@
if (!mInCall && hasValidVibrate && !ringerModeSilent) {
mVibrateNotificationKey = key;
- buzz = playVibration(record, vibration);
+ buzz = playVibration(record, vibration, hasValidSound);
}
}
}
@@ -3788,22 +3789,41 @@
return false;
}
- private boolean playVibration(final NotificationRecord record, long[] vibration) {
+ private boolean playVibration(final NotificationRecord record, long[] vibration,
+ boolean delayVibForSound) {
// Escalate privileges so we can use the vibrator even if the
// notifying app does not have the VIBRATE permission.
long identity = Binder.clearCallingIdentity();
try {
- final boolean insistent =
- (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0;
- final VibrationEffect effect = VibrationEffect.createWaveform(
- vibration, insistent ? 0 : -1 /*repeatIndex*/);
- mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
- effect, record.getAudioAttributes());
+ final VibrationEffect effect;
+ try {
+ final boolean insistent =
+ (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0;
+ effect = VibrationEffect.createWaveform(
+ vibration, insistent ? 0 : -1 /*repeatIndex*/);
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Error creating vibration waveform with pattern: " +
+ Arrays.toString(vibration));
+ return false;
+ }
+ if (delayVibForSound) {
+ new Thread(() -> {
+ // delay the vibration by the same amount as the notification sound
+ final int waitMs = mAudioManager.getFocusRampTimeMs(
+ AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
+ record.getAudioAttributes());
+ if (DBG) Slog.v(TAG, "Delaying vibration by " + waitMs + "ms");
+ try {
+ Thread.sleep(waitMs);
+ } catch (InterruptedException e) { }
+ mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+ effect, record.getAudioAttributes());
+ }).start();
+ } else {
+ mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+ effect, record.getAudioAttributes());
+ }
return true;
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Error creating vibration waveform with pattern: " +
- Arrays.toString(vibration));
- return false;
} finally{
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 95e1db7..f3ae67e 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -73,6 +73,7 @@
public final class NotificationRecord {
static final String TAG = "NotificationRecord";
static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final int MAX_LOGTAG_LENGTH = 35;
final StatusBarNotification sbn;
final int mOriginalFlags;
private final Context mContext;
@@ -127,6 +128,8 @@
private boolean mShowBadge;
private LogMaker mLogMaker;
private Light mLight;
+ private String mGroupLogTag;
+ private String mChannelIdLogTag;
@VisibleForTesting
public NotificationRecord(Context context, StatusBarNotification sbn,
@@ -749,6 +752,37 @@
return sbn.getGroupKey();
}
+ public void setOverrideGroupKey(String overrideGroupKey) {
+ sbn.setOverrideGroupKey(overrideGroupKey);
+ mGroupLogTag = null;
+ }
+
+ private String getGroupLogTag() {
+ if (mGroupLogTag == null) {
+ mGroupLogTag = shortenTag(sbn.getGroup());
+ }
+ return mGroupLogTag;
+ }
+
+ private String getChannelIdLogTag() {
+ if (mChannelIdLogTag == null) {
+ mChannelIdLogTag = shortenTag(mChannel.getId());
+ }
+ return mChannelIdLogTag;
+ }
+
+ private String shortenTag(String longTag) {
+ if (longTag == null) {
+ return null;
+ }
+ if (longTag.length() < MAX_LOGTAG_LENGTH) {
+ return longTag;
+ } else {
+ return longTag.substring(0, MAX_LOGTAG_LENGTH - 8) + "-" +
+ Integer.toHexString(longTag.hashCode());
+ }
+ }
+
public boolean isImportanceFromUser() {
return mImportance == mUserImportance;
}
@@ -806,16 +840,23 @@
public LogMaker getLogMaker(long now) {
if (mLogMaker == null) {
+ // initialize fields that only change on update (so a new record)
mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
.setPackageName(sbn.getPackageName())
.addTaggedData(MetricsEvent.NOTIFICATION_ID, sbn.getId())
- .addTaggedData(MetricsEvent.NOTIFICATION_TAG, sbn.getTag());
+ .addTaggedData(MetricsEvent.NOTIFICATION_TAG, sbn.getTag())
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID, getChannelIdLogTag());
}
+ // reset fields that can change between updates, or are used by multiple logs
return mLogMaker
.clearCategory()
.clearType()
.clearSubtype()
.clearTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX)
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE, mImportance)
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID, getGroupLogTag())
+ .addTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_SUMMARY,
+ sbn.getNotification().isGroupSummary() ? 1 : 0)
.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_CREATE_MILLIS, getLifespanMs(now))
.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_UPDATE_MILLIS, getFreshnessMs(now))
.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS, getExposureMs(now));
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3ca68de..8bd1f79 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3594,13 +3594,14 @@
@Override
public void checkPackageStartable(String packageName, int userId) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
throw new SecurityException("Instant applications don't have access to this method");
}
final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps == null) {
+ if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
throw new SecurityException("Package " + packageName + " was not found!");
}
@@ -3869,15 +3870,26 @@
@Override
public String[] currentToCanonicalPackageNames(String[] names) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return names;
}
- String[] out = new String[names.length];
+ final String[] out = new String[names.length];
// reader
synchronized (mPackages) {
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
for (int i=names.length-1; i>=0; i--) {
- PackageSetting ps = mSettings.mPackages.get(names[i]);
- out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
+ final PackageSetting ps = mSettings.mPackages.get(names[i]);
+ boolean translateName = false;
+ if (ps != null && ps.realName != null) {
+ final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
+ translateName = !targetIsInstantApp
+ || canViewInstantApps
+ || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
+ UserHandle.getAppId(callingUid), ps.appId);
+ }
+ out[i] = translateName ? ps.realName : names[i];
}
}
return out;
@@ -3885,15 +3897,28 @@
@Override
public String[] canonicalToCurrentPackageNames(String[] names) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return names;
}
- String[] out = new String[names.length];
+ final String[] out = new String[names.length];
// reader
synchronized (mPackages) {
+ final int callingUserId = UserHandle.getUserId(callingUid);
+ final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
for (int i=names.length-1; i>=0; i--) {
- String cur = mSettings.getRenamedPackageLPr(names[i]);
- out[i] = cur != null ? cur : names[i];
+ final String cur = mSettings.getRenamedPackageLPr(names[i]);
+ boolean translateName = false;
+ if (cur != null) {
+ final PackageSetting ps = mSettings.mPackages.get(names[i]);
+ final boolean targetIsInstantApp =
+ ps != null && ps.getInstantApp(callingUserId);
+ translateName = !targetIsInstantApp
+ || canViewInstantApps
+ || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
+ UserHandle.getAppId(callingUid), ps.appId);
+ }
+ out[i] = translateName ? cur : names[i];
}
}
return out;
@@ -5303,12 +5328,13 @@
Log.e(TAG, "No such user:" + userId);
return;
}
+ final int callingUid = Binder.getCallingUid();
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
"grantRuntimePermission");
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"grantRuntimePermission");
@@ -5320,11 +5346,18 @@
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
-
final BasePermission bp = mSettings.mPermissions.get(name);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + name);
}
+ sb = (SettingBase) pkg.mExtras;
+ if (sb == null) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ if (sb instanceof PackageSetting
+ && filterAppAccessLPr((PackageSetting) sb, callingUid, userId)) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
@@ -5339,10 +5372,6 @@
}
uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
- sb = (SettingBase) pkg.mExtras;
- if (sb == null) {
- throw new IllegalArgumentException("Unknown package: " + packageName);
- }
final PermissionsState permissionsState = sb.getPermissionsState();
@@ -5612,7 +5641,8 @@
enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, false /* checkShell */,
"getPermissionFlags");
@@ -5621,17 +5651,18 @@
if (pkg == null) {
return 0;
}
-
final BasePermission bp = mSettings.mPermissions.get(name);
if (bp == null) {
return 0;
}
-
- SettingBase sb = (SettingBase) pkg.mExtras;
+ final SettingBase sb = (SettingBase) pkg.mExtras;
if (sb == null) {
return 0;
}
-
+ if (sb instanceof PackageSetting
+ && filterAppAccessLPr((PackageSetting) sb, callingUid, userId)) {
+ return 0;
+ }
PermissionsState permissionsState = sb.getPermissionsState();
return permissionsState.getPermissionFlags(name, userId);
}
@@ -6172,7 +6203,8 @@
@Override
public int getFlagsForUid(int uid) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return 0;
}
synchronized (mPackages) {
@@ -6182,6 +6214,9 @@
return sus.pkgFlags;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
+ if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+ return 0;
+ }
return ps.pkgFlags;
}
}
@@ -6190,7 +6225,8 @@
@Override
public int getPrivateFlagsForUid(int uid) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return 0;
}
synchronized (mPackages) {
@@ -6200,6 +6236,9 @@
return sus.pkgPrivateFlags;
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
+ if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+ return 0;
+ }
return ps.pkgPrivateFlags;
}
}
@@ -8049,13 +8088,14 @@
@Override
public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return ParceledListSlice.emptyList();
}
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForPackage(flags, userId, null);
final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, false /* checkShell */,
"get installed packages");
@@ -8065,9 +8105,12 @@
if (listUninstalled) {
list = new ArrayList<>(mSettings.mPackages.size());
for (PackageSetting ps : mSettings.mPackages.values()) {
- if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
continue;
}
+ if (filterAppAccessLPr(ps, callingUid, userId)) {
+ return null;
+ }
final PackageInfo pi = generatePackageInfo(ps, flags, userId);
if (pi != null) {
list.add(pi);
@@ -8076,10 +8119,13 @@
} else {
list = new ArrayList<>(mPackages.size());
for (PackageParser.Package p : mPackages.values()) {
- if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
- Binder.getCallingUid(), userId, flags)) {
+ final PackageSetting ps = (PackageSetting) p.mExtras;
+ if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
continue;
}
+ if (filterAppAccessLPr(ps, callingUid, userId)) {
+ return null;
+ }
final PackageInfo pi = generatePackageInfo((PackageSetting)
p.mExtras, flags, userId);
if (pi != null) {
@@ -8166,7 +8212,8 @@
@Override
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return ParceledListSlice.emptyList();
}
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
@@ -8185,9 +8232,12 @@
effectiveFlags |= PackageManager.MATCH_ANY_USER;
}
if (ps.pkg != null) {
- if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
+ if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
continue;
}
+ if (filterAppAccessLPr(ps, callingUid, userId)) {
+ return null;
+ }
ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
ps.readUserState(userId), userId);
if (ai != null) {
@@ -8198,7 +8248,7 @@
// Shared lib filtering done in generateApplicationInfoFromSettingsLPw
// and already converts to externally visible package name
ai = generateApplicationInfoFromSettingsLPw(ps.name,
- Binder.getCallingUid(), effectiveFlags, userId);
+ callingUid, effectiveFlags, userId);
}
if (ai != null) {
list.add(ai);
@@ -8212,6 +8262,9 @@
if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
continue;
}
+ if (filterAppAccessLPr(ps, callingUid, userId)) {
+ return null;
+ }
ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
@@ -9404,6 +9457,11 @@
@Override
public boolean performDexOpt(String packageName,
boolean checkProfiles, int compileReason, boolean force, boolean bootComplete) {
+ if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ return false;
+ } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
+ return false;
+ }
int dexoptStatus = performDexOptWithStatus(
packageName, checkProfiles, compileReason, force, bootComplete);
return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
@@ -9427,6 +9485,8 @@
boolean bootComplete) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return false;
+ } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
+ return false;
}
int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
targetCompilerFilter, force, bootComplete);
@@ -9526,6 +9586,8 @@
boolean force) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return false;
+ } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
+ return false;
}
mDexManager.reconcileSecondaryDexFiles(packageName);
return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
@@ -14422,19 +14484,23 @@
@Override
public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, false /* checkShell */,
"getApplicationHidden for user " + userId);
- PackageSetting pkgSetting;
+ PackageSetting ps;
long callingId = Binder.clearCallingIdentity();
try {
// writer
synchronized (mPackages) {
- pkgSetting = mSettings.mPackages.get(packageName);
- if (pkgSetting == null) {
+ ps = mSettings.mPackages.get(packageName);
+ if (ps == null) {
return true;
}
- return pkgSetting.getHidden(userId);
+ if (filterAppAccessLPr(ps, callingUid, userId)) {
+ return true;
+ }
+ return ps.getHidden(userId);
}
} finally {
Binder.restoreCallingIdentity(callingId);
@@ -14450,8 +14516,8 @@
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
null);
PackageSetting pkgSetting;
- final int uid = Binder.getCallingUid();
- enforceCrossUserPermission(uid, userId,
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"installExistingPackage for user " + userId);
if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
@@ -14934,10 +15000,16 @@
@Override
public int getIntentVerificationStatus(String packageName, int userId) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
}
synchronized (mPackages) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps == null
+ || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+ return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
+ }
return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
}
}
@@ -14960,10 +15032,15 @@
@Override
public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
String packageName) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return ParceledListSlice.emptyList();
}
synchronized (mPackages) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+ return ParceledListSlice.emptyList();
+ }
return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
}
}
@@ -17129,12 +17206,15 @@
@Override
public List<String> getPreviousCodePaths(String packageName) {
+ final int callingUid = Binder.getCallingUid();
final List<String> result = new ArrayList<>();
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ if (getInstantAppPackageName(callingUid) != null) {
return result;
}
final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null && ps.oldCodePaths != null) {
+ if (ps != null
+ && ps.oldCodePaths != null
+ && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
result.addAll(ps.oldCodePaths);
}
return result;
@@ -18364,8 +18444,11 @@
@Override
public void deletePackageVersioned(VersionedPackage versionedPackage,
final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
+ final int callingUid = Binder.getCallingUid();
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null);
+ final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_INSTANT_APPS);
Preconditions.checkNotNull(versionedPackage);
Preconditions.checkNotNull(observer);
Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
@@ -18430,33 +18513,45 @@
public void run() {
mHandler.removeCallbacks(this);
int returnCode;
- if (!deleteAllUsers) {
- returnCode = deletePackageX(internalPackageName, versionCode,
- userId, deleteFlags);
- } else {
- int[] blockUninstallUserIds = getBlockUninstallForUsers(
- internalPackageName, users);
- // If nobody is blocking uninstall, proceed with delete for all users
- if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
+ final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
+ boolean doDeletePackage = true;
+ if (ps != null) {
+ final boolean targetIsInstantApp =
+ ps.getInstantApp(UserHandle.getUserId(callingUid));
+ doDeletePackage = !targetIsInstantApp
+ || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
+ }
+ if (doDeletePackage) {
+ if (!deleteAllUsers) {
returnCode = deletePackageX(internalPackageName, versionCode,
userId, deleteFlags);
} else {
- // Otherwise uninstall individually for users with blockUninstalls=false
- final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
- for (int userId : users) {
- if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
- returnCode = deletePackageX(internalPackageName, versionCode,
- userId, userFlags);
- if (returnCode != PackageManager.DELETE_SUCCEEDED) {
- Slog.w(TAG, "Package delete failed for user " + userId
- + ", returnCode " + returnCode);
+ int[] blockUninstallUserIds = getBlockUninstallForUsers(
+ internalPackageName, users);
+ // If nobody is blocking uninstall, proceed with delete for all users
+ if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
+ returnCode = deletePackageX(internalPackageName, versionCode,
+ userId, deleteFlags);
+ } else {
+ // Otherwise uninstall individually for users with blockUninstalls=false
+ final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
+ for (int userId : users) {
+ if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
+ returnCode = deletePackageX(internalPackageName, versionCode,
+ userId, userFlags);
+ if (returnCode != PackageManager.DELETE_SUCCEEDED) {
+ Slog.w(TAG, "Package delete failed for user " + userId
+ + ", returnCode " + returnCode);
+ }
}
}
+ // The app has only been marked uninstalled for certain users.
+ // We still need to report that delete was blocked
+ returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
}
- // The app has only been marked uninstalled for certain users.
- // We still need to report that delete was blocked
- returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
}
+ } else {
+ returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
}
try {
observer.onPackageDeleted(packageName, returnCode, null);
@@ -19267,6 +19362,10 @@
@Override
public boolean getBlockUninstallForUser(String packageName, int userId) {
synchronized (mPackages) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
+ return true;
+ }
return mSettings.getBlockUninstallLPr(userId, packageName);
}
}
@@ -19616,9 +19715,14 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_USER_DATA, null);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ final int callingUid = Binder.getCallingUid();
+ enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, false /* checkShell */, "clear application data");
+ final PackageSetting ps = mSettings.getPackageLPr(packageName);
+ if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
+ return;
+ }
if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
throw new SecurityException("Cannot clear data for a protected package: "
+ packageName);
@@ -19876,11 +19980,14 @@
@Override
public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
final IPackageDataObserver observer) {
+ final int callingUid = Binder.getCallingUid();
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_CACHE_FILES, null);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ enforceCrossUserPermission(callingUid, userId,
/* requireFullPermission= */ true, /* checkShell= */ false,
"delete application cache files");
+ final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_INSTANT_APPS);
final PackageParser.Package pkg;
synchronized (mPackages) {
@@ -19890,15 +19997,25 @@
// Queue up an async operation since the package deletion may take a little while.
mHandler.post(new Runnable() {
public void run() {
- synchronized (mInstallLock) {
- final int flags = StorageManager.FLAG_STORAGE_DE
- | StorageManager.FLAG_STORAGE_CE;
- // We're only clearing cache files, so we don't care if the
- // app is unfrozen and still able to run
- clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
- clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ boolean doClearData = true;
+ if (ps != null) {
+ final boolean targetIsInstantApp =
+ ps.getInstantApp(UserHandle.getUserId(callingUid));
+ doClearData = !targetIsInstantApp
+ || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
}
- clearExternalStorageDataSync(packageName, userId, false);
+ if (doClearData) {
+ synchronized (mInstallLock) {
+ final int flags = StorageManager.FLAG_STORAGE_DE
+ | StorageManager.FLAG_STORAGE_CE;
+ // We're only clearing cache files, so we don't care if the
+ // app is unfrozen and still able to run
+ clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
+ clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
+ }
+ clearExternalStorageDataSync(packageName, userId, false);
+ }
if (observer != null) {
try {
observer.onRemoveCompleted(packageName, true);
@@ -20148,7 +20265,11 @@
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
}
}
-
+ final PackageSetting ps = mSettings.getPackageLPr(packageName);
+ if (ps != null
+ && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
+ return;
+ }
int user = UserHandle.getCallingUserId();
if (clearPackagePreferredActivitiesLPw(packageName, user)) {
scheduleWritePackageRestrictionsLocked(user);
@@ -20798,7 +20919,7 @@
public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
- int callingUid = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
enforceOwnerRights(ownerPackage, callingUid);
enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
synchronized (mPackages) {
@@ -20821,7 +20942,7 @@
if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
return;
}
- int callingUserId = UserHandle.getUserId(callingUid);
+ final int callingUserId = UserHandle.getUserId(callingUid);
PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
if (pi == null) {
throw new IllegalArgumentException("Unknown package " + pkg + " on user "
@@ -23460,13 +23581,14 @@
public int movePackage(final String packageName, final String volumeUuid) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
- final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
+ final int callingUid = Binder.getCallingUid();
+ final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
final int moveId = mNextMoveId.getAndIncrement();
mHandler.post(new Runnable() {
@Override
public void run() {
try {
- movePackageInternal(packageName, volumeUuid, moveId, user);
+ movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to move " + packageName, e);
mMoveCallbacks.notifyStatusChanged(moveId,
@@ -23478,7 +23600,8 @@
}
private void movePackageInternal(final String packageName, final String volumeUuid,
- final int moveId, UserHandle user) throws PackageManagerException {
+ final int moveId, final int callingUid, UserHandle user)
+ throws PackageManagerException {
final StorageManager storage = mContext.getSystemService(StorageManager.class);
final PackageManager pm = mContext.getPackageManager();
@@ -23498,10 +23621,11 @@
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (pkg == null || ps == null) {
+ if (pkg == null
+ || ps == null
+ || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
}
-
if (pkg.applicationInfo.isSystemApp()) {
throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
"Cannot move system application");
@@ -23971,6 +24095,11 @@
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
+ Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
KeySetManagerService ksms = mSettings.mKeySetManagerService;
return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
}
@@ -24687,9 +24816,6 @@
@Override
public boolean canRequestPackageInstalls(String packageName, int userId) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
- return false;
- }
return canRequestPackageInstallsInternal(packageName, 0, userId,
true /* throwIfPermNotDeclared*/);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 76d5c33..6aba9cb 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1418,7 +1418,7 @@
launchHomeFromHotKey();
break;
case SHORT_PRESS_POWER_GO_HOME:
- launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
+ shortPressPowerGoHome();
break;
case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: {
if (mDismissImeOnBackKeyPressed) {
@@ -1430,8 +1430,7 @@
mInputMethodManagerInternal.hideCurrentInputMethod();
}
} else {
- launchHomeFromHotKey(true /* awakenFromDreams */,
- false /*respectKeyguard*/);
+ shortPressPowerGoHome();
}
break;
}
@@ -1439,6 +1438,15 @@
}
}
+ private void shortPressPowerGoHome() {
+ launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/);
+ if (isKeyguardShowingAndNotOccluded()) {
+ // Notify keyguard so it can do any special handling for the power button since the
+ // device will not power off and only launch home.
+ mKeyguardDelegate.onShortPowerPressedGoHome();
+ }
+ }
+
private void powerMultiPressAction(long eventTime, boolean interactive, int behavior) {
switch (behavior) {
case MULTI_PRESS_POWER_NOTHING:
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index da90e5a..0121ee1 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -372,6 +372,12 @@
mKeyguardState.bootCompleted = true;
}
+ public void onShortPowerPressedGoHome() {
+ if (mKeyguardService != null) {
+ mKeyguardService.onShortPowerPressedGoHome();
+ }
+ }
+
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + TAG);
prefix += " ";
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
index 0b839b8..425be54 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java
@@ -218,6 +218,15 @@
}
}
+ @Override
+ public void onShortPowerPressedGoHome() {
+ try {
+ mService.onShortPowerPressedGoHome();
+ } catch (RemoteException e) {
+ Slog.w(TAG , "Remote Exception", e);
+ }
+ }
+
@Override // Binder interface
public IBinder asBinder() {
return mService.asBinder();
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index fe90ba9..d4949b6 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -278,6 +278,7 @@
pw.println("Current WebView Update Service state");
pw.println(String.format(" Fallback logic enabled: %b",
mSystemInterface.isFallbackLogicEnabled()));
+ pw.println(String.format(" Multiprocess enabled: %b", isMultiProcessEnabled()));
mWebViewUpdater.dumpState(pw);
}
}
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index 972623c..7eebe39 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -25,6 +25,7 @@
import android.app.Notification;
import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
@@ -45,6 +46,7 @@
private static final int NOTIFICATION_ID = 0;
private static int sNextRequestCode = 0;
+ private static NotificationChannelGroup sChannelGroup;
private final int mRequestCode;
private final WindowManagerService mService;
private String mNotificationTag;
@@ -61,6 +63,12 @@
mNotificationTag = CHANNEL_PREFIX + mPackageName;
mRequestCode = sNextRequestCode++;
mIconUtilities = new IconUtilities(mService.mContext);
+ if (sChannelGroup == null) {
+ sChannelGroup = new NotificationChannelGroup(CHANNEL_PREFIX,
+ mService.mContext.getString(
+ R.string.alert_windows_notification_channel_group_name));
+ mNotificationManager.createNotificationChannelGroup(sChannelGroup);
+ }
}
void post() {
@@ -142,6 +150,7 @@
channel.enableLights(false);
channel.enableVibration(false);
channel.setBlockableSystem(true);
+ channel.setGroup(sChannelGroup.getId());
mNotificationManager.createNotificationChannel(channel);
}
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 1a685eb..6640184 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -19,7 +19,6 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -381,6 +380,7 @@
// if made visible again.
wtoken.removeDeadWindows();
wtoken.setVisibleBeforeClientHidden();
+ mService.mUnknownAppVisibilityController.appRemovedOrHidden(wtoken);
} else {
if (!mService.mAppTransition.isTransitionSet()
&& mService.mAppTransition.isReady()) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 37ebfd3..525e0ff 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -52,7 +52,6 @@
import android.annotation.NonNull;
import android.app.Activity;
-import android.app.ActivityManager;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
@@ -526,7 +525,7 @@
boolean delayed = setVisibility(null, false, TRANSIT_UNSET, true, mVoiceInteraction);
mService.mOpeningApps.remove(this);
- mService.mUnknownAppVisibilityController.appRemoved(this);
+ mService.mUnknownAppVisibilityController.appRemovedOrHidden(this);
mService.mTaskSnapshotController.onAppRemoved(this);
waitingToShow = false;
if (mService.mClosingApps.contains(this)) {
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 818df01..bfebca8 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -163,6 +163,8 @@
@VisibleForTesting
boolean shouldDeferRemoval() {
+ // TODO: This should probably return false if mChildren.isEmpty() regardless if the stack
+ // is animating...
return hasWindowsAlive() && mStack.isAnimating();
}
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
index 8f4f09e..eb751fa 100644
--- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -84,9 +84,9 @@
return builder.toString();
}
- void appRemoved(@NonNull AppWindowToken appWindow) {
+ void appRemovedOrHidden(@NonNull AppWindowToken appWindow) {
if (DEBUG_UNKNOWN_APP_VISIBILITY) {
- Slog.d(TAG, "App removed appWindow=" + appWindow);
+ Slog.d(TAG, "App removed or hidden appWindow=" + appWindow);
}
mUnknownApps.remove(appWindow);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 02fdfee..9d1b3d9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -617,6 +617,11 @@
WindowState mCurrentFocus = null;
WindowState mLastFocus = null;
+ /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
+ private final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
+ /** Windows removed since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
+ private final ArrayList<WindowState> mWinRemovedSinceNullFocus = new ArrayList<>();
+
/** This just indicates the window the input method is on top of, not
* necessarily the window its input is going to. */
WindowState mInputMethodTarget = null;
@@ -1381,6 +1386,9 @@
// From now on, no exceptions or errors allowed!
res = WindowManagerGlobal.ADD_OKAY;
+ if (mCurrentFocus == null) {
+ mWinAddedSinceNullFocus.add(win);
+ }
if (excludeWindowTypeFromTapOutTask(type)) {
displayContent.mTapExcludedWindows.add(win);
@@ -1667,6 +1675,9 @@
mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
}
+ if (mCurrentFocus == null) {
+ mWinRemovedSinceNullFocus.add(win);
+ }
mPendingRemove.remove(win);
mResizingWindows.remove(win);
mWindowsChanged = true;
@@ -5804,6 +5815,11 @@
mCurrentFocus = newFocus;
mLosingFocus.remove(newFocus);
+ if (mCurrentFocus != null) {
+ mWinAddedSinceNullFocus.clear();
+ mWinRemovedSinceNullFocus.clear();
+ }
+
int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
if (imWindowChanged && oldFocus != mInputMethodWindow) {
@@ -6538,6 +6554,12 @@
if (reason != null) {
pw.println(" Reason: " + reason);
}
+ if (!mWinAddedSinceNullFocus.isEmpty()) {
+ pw.println(" Windows added since null focus: " + mWinAddedSinceNullFocus);
+ }
+ if (!mWinRemovedSinceNullFocus.isEmpty()) {
+ pw.println(" Windows removed since null focus: " + mWinRemovedSinceNullFocus);
+ }
pw.println();
dumpWindowsNoHeaderLocked(pw, true, null);
pw.println();
diff --git a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 39caa3c..ec08874 100644
--- a/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/notification/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -61,6 +61,7 @@
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -102,6 +103,7 @@
private static final long[] FALLBACK_VIBRATION_PATTERN = new long[] {100, 100, 100};
private static final VibrationEffect FALLBACK_VIBRATION =
VibrationEffect.createWaveform(FALLBACK_VIBRATION_PATTERN, -1);
+ private static final int MAX_VIBRATION_DELAY = 1000;
@Before
public void setUp() {
@@ -309,6 +311,11 @@
(AudioAttributes) anyObject());
}
+ private void verifyDelayedVibrateLooped() {
+ verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
+ argThat(mVibrateLoopMatcher), (AudioAttributes) anyObject());
+ }
+
private void verifyStopVibrate() {
verify(mVibrator, times(1)).cancel();
}
@@ -506,8 +513,8 @@
VibrationEffect effect = VibrationEffect.createWaveform(r.getVibration(), -1);
- verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(effect),
- (AudioAttributes) anyObject());
+ verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
+ eq(effect), (AudioAttributes) anyObject());
}
@Test
@@ -521,8 +528,8 @@
mService.buzzBeepBlinkLocked(r);
- verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), eq(FALLBACK_VIBRATION),
- (AudioAttributes) anyObject());
+ verify(mVibrator, timeout(MAX_VIBRATION_DELAY).times(1)).vibrate(anyInt(), anyString(),
+ eq(FALLBACK_VIBRATION), (AudioAttributes) anyObject());
verify(mRingtonePlayer, never()).playAsync
(anyObject(), anyObject(), anyBoolean(), anyObject());
}
@@ -539,7 +546,7 @@
mService.buzzBeepBlinkLocked(r);
- verifyVibrateLooped();
+ verifyDelayedVibrateLooped();
}
@Test
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 5c40a2c..dfc69ea 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -93,6 +93,8 @@
private TestableLooper mTestableLooper;
@Mock
private RankingHelper mRankingHelper;
+ @Mock
+ private NotificationUsageStats mUsageStats;
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
@Mock
@@ -149,7 +151,7 @@
when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
mNotificationManagerService.init(mTestableLooper.getLooper(), mPackageManager,
mPackageManagerClient, mockLightsManager, mNotificationListeners, mCompanionMgr,
- mSnoozeHelper);
+ mSnoozeHelper, mUsageStats);
// Tests call directly into the Binder.
mBinderService = mNotificationManagerService.getBinderService();
@@ -263,40 +265,37 @@
@Test
public void testBlockedNotifications_suspended() throws Exception {
- NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(true);
NotificationChannel channel = new NotificationChannel("id", "name",
NotificationManager.IMPORTANCE_HIGH);
NotificationRecord r = generateNotificationRecord(channel);
- assertTrue(mNotificationManagerService.isBlocked(r, usageStats));
- verify(usageStats, times(1)).registerSuspendedByAdmin(eq(r));
+ assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats));
+ verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r));
}
@Test
public void testBlockedNotifications_blockedChannel() throws Exception {
- NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
NotificationChannel channel = new NotificationChannel("id", "name",
NotificationManager.IMPORTANCE_HIGH);
channel.setImportance(NotificationManager.IMPORTANCE_NONE);
NotificationRecord r = generateNotificationRecord(channel);
- assertTrue(mNotificationManagerService.isBlocked(r, usageStats));
- verify(usageStats, times(1)).registerBlocked(eq(r));
+ assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats));
+ verify(mUsageStats, times(1)).registerBlocked(eq(r));
}
@Test
public void testBlockedNotifications_blockedApp() throws Exception {
- NotificationUsageStats usageStats = mock(NotificationUsageStats.class);
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
NotificationChannel channel = new NotificationChannel("id", "name",
NotificationManager.IMPORTANCE_HIGH);
NotificationRecord r = generateNotificationRecord(channel);
r.setUserImportance(NotificationManager.IMPORTANCE_NONE);
- assertTrue(mNotificationManagerService.isBlocked(r, usageStats));
- verify(usageStats, times(1)).registerBlocked(eq(r));
+ assertTrue(mNotificationManagerService.isBlocked(r, mUsageStats));
+ verify(mUsageStats, times(1)).registerBlocked(eq(r));
}
@Test
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
index 0812783..5a6225a 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationRecordTest.java
@@ -35,6 +35,7 @@
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.media.AudioAttributes;
+import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Build;
import android.os.UserHandle;
@@ -44,6 +45,8 @@
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -71,6 +74,14 @@
private final String channelId = "channel";
NotificationChannel channel =
new NotificationChannel(channelId, "test", NotificationManager.IMPORTANCE_DEFAULT);
+ private final String channelIdLong =
+ "give_a_developer_a_string_argument_and_who_knows_what_they_will_pass_in_there";
+ final String groupId = "group";
+ final String groupIdOverride = "other_group";
+ private final String groupIdLong =
+ "0|com.foo.bar|g:content://com.foo.bar.ui/account%3A-0000000/account/";
+ NotificationChannel channelLongId =
+ new NotificationChannel(channelIdLong, "long", NotificationManager.IMPORTANCE_DEFAULT);
NotificationChannel defaultChannel =
new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "test",
NotificationManager.IMPORTANCE_UNSPECIFIED);
@@ -107,7 +118,8 @@
}
private StatusBarNotification getNotification(boolean preO, boolean noisy, boolean defaultSound,
- boolean buzzy, boolean defaultVibration, boolean lights, boolean defaultLights) {
+ boolean buzzy, boolean defaultVibration, boolean lights, boolean defaultLights,
+ String group) {
when(mMockContext.getApplicationInfo()).thenReturn(preO ? legacy : upgrade);
final Builder builder = new Builder(mMockContext)
.setContentTitle("foo")
@@ -151,6 +163,9 @@
builder.setChannelId(channelId);
}
+ if(group != null) {
+ builder.setGroup(group);
+ }
Notification n = builder.build();
if (preO) {
@@ -172,7 +187,7 @@
// pre upgrade, default sound.
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(Settings.System.DEFAULT_NOTIFICATION_URI, record.getSound());
@@ -185,7 +200,7 @@
// pre upgrade, custom sound.
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_SOUND, record.getSound());
@@ -199,7 +214,7 @@
// pre upgrade, default sound.
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_SOUND, record.getSound());
@@ -211,7 +226,7 @@
// pre upgrade, default sound.
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(null, record.getSound());
@@ -224,7 +239,7 @@
// post upgrade, default sound.
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(CUSTOM_SOUND, record.getSound());
@@ -237,7 +252,7 @@
// pre upgrade, default vibration.
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, true /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertNotNull(record.getVibration());
@@ -249,7 +264,7 @@
// pre upgrade, custom vibration.
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_VIBRATION, record.getVibration());
@@ -262,7 +277,7 @@
// pre upgrade, custom vibration.
StatusBarNotification sbn = getNotification(true /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertTrue(!Objects.equals(CUSTOM_VIBRATION, record.getVibration()));
@@ -274,7 +289,7 @@
// post upgrade, custom vibration.
StatusBarNotification sbn = getNotification(false /*preO */, false /* noisy */,
false /* defaultSound */, true /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(CUSTOM_CHANNEL_VIBRATION, record.getVibration());
@@ -284,7 +299,7 @@
public void testImportance_preUpgrade() throws Exception {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(NotificationManager.IMPORTANCE_HIGH, record.getImportance());
}
@@ -295,7 +310,7 @@
defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(NotificationManager.IMPORTANCE_LOW, record.getImportance());
@@ -307,7 +322,7 @@
defaultChannel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(NotificationManager.IMPORTANCE_HIGH, record.getImportance());
@@ -317,7 +332,7 @@
public void testImportance_upgrade() throws Exception {
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(NotificationManager.IMPORTANCE_DEFAULT, record.getImportance());
}
@@ -326,7 +341,7 @@
public void testLights_preUpgrade_noLight() throws Exception {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertNull(record.getLight());
}
@@ -336,7 +351,7 @@
public void testLights_preUpgrade() throws Exception {
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- true /* lights */, false /*defaultLights */);
+ true /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertEquals(CUSTOM_LIGHT, record.getLight());
}
@@ -347,7 +362,7 @@
defaultChannel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
StatusBarNotification sbn = getNotification(true /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- true /* lights */, false /*defaultLights */);
+ true /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertFalse(CUSTOM_LIGHT.equals(record.getLight()));
@@ -366,7 +381,7 @@
defaultLightColor, defaultLightOn, defaultLightOff);
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- true /* lights */, true /*defaultLights */);
+ true /* lights */, true /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(expected, record.getLight());
}
@@ -382,7 +397,7 @@
Color.BLUE, defaultLightOn, defaultLightOff);
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- true /* lights */, false /*defaultLights */);
+ true /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
assertEquals(expected, record.getLight());
}
@@ -391,8 +406,80 @@
public void testLights_upgrade_noLight() throws Exception {
StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
- false /* lights */, false /*defaultLights */);
+ false /* lights */, false /* defaultLights */, null /* group */);
NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
assertNull(record.getLight());
}
+
+ @Test
+ public void testLogmakerShortChannel() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, null /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ final LogMaker logMaker = record.getLogMaker();
+ assertEquals(channelId,
+ (String) logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID));
+ assertEquals(channel.getImportance(),
+ logMaker.getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_IMPORTANCE));
+ }
+
+ @Test
+ public void testLogmakerLongChannel() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /*defaultLights */, null /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channelLongId);
+ final String loggedId = (String)
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_CHANNEL_ID);
+ assertEquals(channelIdLong.substring(0,10), loggedId.substring(0, 10));
+ }
+
+ @Test
+ public void testLogmakerNoGroup() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /*defaultLights */, null /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ assertNull(record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ }
+
+ @Test
+ public void testLogmakerShortGroup() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*reO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, groupId /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ assertEquals(groupId,
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ }
+
+ @Test
+ public void testLogmakerLongGroup() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, groupIdLong /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ final String loggedId = (String)
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID);
+ assertEquals(groupIdLong.substring(0,10), loggedId.substring(0, 10));
+ }
+
+ @Test
+ public void testLogmakerOverrideGroup() throws Exception {
+ StatusBarNotification sbn = getNotification(false /*preO */, true /* noisy */,
+ true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+ false /* lights */, false /* defaultLights */, groupId /* group */);
+ NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+ assertEquals(groupId,
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ record.setOverrideGroupKey(groupIdOverride);
+ assertEquals(groupIdOverride,
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ record.setOverrideGroupKey(null);
+ assertEquals(groupId,
+ record.getLogMaker().getTaggedData(MetricsEvent.FIELD_NOTIFICATION_GROUP_ID));
+ }
+
+
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 5a4bb27..4a22a29 100644
--- a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -82,7 +82,7 @@
public void testAppRemoved() throws Exception {
final AppWindowToken token = new WindowTestUtils.TestAppWindowToken(mDisplayContent);
sWm.mUnknownAppVisibilityController.notifyLaunched(token);
- sWm.mUnknownAppVisibilityController.appRemoved(token);
+ sWm.mUnknownAppVisibilityController.appRemovedOrHidden(token);
assertTrue(sWm.mUnknownAppVisibilityController.allResolved());
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 0c5e4bd..3788cf33 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -16,6 +16,8 @@
package com.android.server.voiceinteraction;
+import static android.app.ActivityManager.START_ASSISTANT_HIDDEN_SESSION;
+import static android.app.ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION;
import static android.app.ActivityManager.START_VOICE_HIDDEN_SESSION;
import static android.app.ActivityManager.START_VOICE_NOT_ACTIVE_SESSION;
@@ -212,11 +214,11 @@
try {
if (mActiveSession == null || token != mActiveSession.mToken) {
Slog.w(TAG, "startAssistantActivity does not match active session");
- return START_VOICE_NOT_ACTIVE_SESSION;
+ return START_ASSISTANT_NOT_ACTIVE_SESSION;
}
if (!mActiveSession.mShown) {
Slog.w(TAG, "startAssistantActivity not allowed on hidden session");
- return START_VOICE_HIDDEN_SESSION;
+ return START_ASSISTANT_HIDDEN_SESSION;
}
intent = new Intent(intent);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 4267ec4..d394d63 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -453,6 +453,7 @@
mShowFlags = 0;
mHaveAssistData = false;
mAssistData.clear();
+ mPendingShowCallbacks.clear();
if (mSession != null) {
try {
mSession.hide();
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index e53e246..9513517 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -252,6 +252,12 @@
*/
public static final int WIFI_LOST = 59;
+ /**
+ * The call has failed because of access class barring.
+ * {@hide}
+ */
+ public static final int IMS_ACCESS_BLOCKED = 60;
+
//*********************************************************************************************
// When adding a disconnect type:
// 1) Update toString() with the newly added disconnect type.
@@ -384,6 +390,8 @@
return "IMEI_NOT_ACCEPTED";
case WIFI_LOST:
return "WIFI_LOST";
+ case IMS_ACCESS_BLOCKED:
+ return "IMS_ACCESS_BLOCKED";
default:
return "INVALID: " + cause;
}
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 272653f..4d2f97f 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -664,7 +664,8 @@
if (lineCount == 2 && line.contains(SUCCESS_MESSAGE)) {
launchSuccess = true;
}
- if (launchSuccess && lineCount == 4) {
+ // Parse TotalTime which is the launch time
+ if (launchSuccess && lineCount == 5) {
String launchSplit[] = line.split(":");
launchTime = launchSplit[1].trim();
}
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
index 3af0adc..e4bf590 100644
--- a/tests/net/Android.mk
+++ b/tests/net/Android.mk
@@ -42,6 +42,7 @@
libui \
libunwind \
libutils \
+ libvndksupport \
libcrypto \
libhidl-gen-utils \
libhidlbase \
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 241b828..b6922d4 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -16,6 +16,12 @@
package com.android.server.connectivity;
+import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
+import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
+import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyBoolean;
@@ -222,12 +228,22 @@
private void sendWifiApStateChanged(int state) {
final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
- intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, state);
+ intent.putExtra(EXTRA_WIFI_AP_STATE, state);
mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- private void verifyInterfaceServingModeStarted() throws Exception {
- verify(mNMService, times(1)).listInterfaces();
+ private void sendWifiApStateChanged(int state, String ifname, int ipmode) {
+ final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
+ intent.putExtra(EXTRA_WIFI_AP_STATE, state);
+ intent.putExtra(EXTRA_WIFI_AP_INTERFACE_NAME, ifname);
+ intent.putExtra(EXTRA_WIFI_AP_MODE, ipmode);
+ mServiceContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
+
+ private void verifyInterfaceServingModeStarted(boolean ifnameKnown) throws Exception {
+ if (!ifnameKnown) {
+ verify(mNMService, times(1)).listInterfaces();
+ }
verify(mNMService, times(1)).getInterfaceConfig(mTestIfname);
verify(mNMService, times(1))
.setInterfaceConfig(eq(mTestIfname), any(InterfaceConfiguration.class));
@@ -243,18 +259,21 @@
mIntents.remove(bcast);
}
- @Test
- public void workingLocalOnlyHotspot() throws Exception {
+ public void workingLocalOnlyHotspot(boolean enrichedApBroadcast) throws Exception {
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
// Emulate externally-visible WifiManager effects, causing the
// per-interface state machine to start up, and telling us that
// hotspot mode is to be started.
mTethering.interfaceStatusChanged(mTestIfname, true);
- sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED);
+ if (enrichedApBroadcast) {
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_LOCAL_ONLY);
+ } else {
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
+ }
mLooper.dispatchAll();
- verifyInterfaceServingModeStarted();
+ verifyInterfaceServingModeStarted(enrichedApBroadcast);
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
verify(mNMService, times(1)).setIpForwardingEnabled(true);
verify(mNMService, times(1)).startTethering(any(String[].class));
@@ -295,7 +314,16 @@
}
@Test
- public void workingWifiTethering() throws Exception {
+ public void workingLocalOnlyHotspotLegacyApBroadcast() throws Exception {
+ workingLocalOnlyHotspot(false);
+ }
+
+ @Test
+ public void workingLocalOnlyHotspotEnrichedApBroadcast() throws Exception {
+ workingLocalOnlyHotspot(true);
+ }
+
+ public void workingWifiTethering(boolean enrichedApBroadcast) throws Exception {
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
@@ -311,10 +339,14 @@
// per-interface state machine to start up, and telling us that
// tethering mode is to be started.
mTethering.interfaceStatusChanged(mTestIfname, true);
- sendWifiApStateChanged(WifiManager.WIFI_AP_STATE_ENABLED);
+ if (enrichedApBroadcast) {
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, mTestIfname, IFACE_IP_MODE_TETHERED);
+ } else {
+ sendWifiApStateChanged(WIFI_AP_STATE_ENABLED);
+ }
mLooper.dispatchAll();
- verifyInterfaceServingModeStarted();
+ verifyInterfaceServingModeStarted(enrichedApBroadcast);
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_AVAILABLE_TETHER);
verify(mNMService, times(1)).setIpForwardingEnabled(true);
verify(mNMService, times(1)).startTethering(any(String[].class));
@@ -376,6 +408,16 @@
}
@Test
+ public void workingWifiTetheringLegacyApBroadcast() throws Exception {
+ workingWifiTethering(false);
+ }
+
+ @Test
+ public void workingWifiTetheringEnrichedApBroadcast() throws Exception {
+ workingWifiTethering(true);
+ }
+
+ @Test
public void failureEnablingIpForwarding() throws Exception {
when(mConnectivityManager.isTetheringSupported()).thenReturn(true);
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
diff --git a/tests/testables/src/android/testing/ViewUtils.java b/tests/testables/src/android/testing/ViewUtils.java
index 7478998..1c6016e 100644
--- a/tests/testables/src/android/testing/ViewUtils.java
+++ b/tests/testables/src/android/testing/ViewUtils.java
@@ -39,8 +39,7 @@
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
LayoutParams.TYPE_APPLICATION_OVERLAY,
0, PixelFormat.TRANSLUCENT);
- InstrumentationRegistry.getContext()
- .getSystemService(WindowManager.class).addView(view, lp);
+ view.getContext().getSystemService(WindowManager.class).addView(view, lp);
}
/**
@@ -49,7 +48,6 @@
* This is currently done by removing the view from a window.
*/
public static void detachView(View view) {
- InstrumentationRegistry.getContext()
- .getSystemService(WindowManager.class).removeViewImmediate(view);
+ view.getContext().getSystemService(WindowManager.class).removeViewImmediate(view);
}
}
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index bc13378..084325a 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -415,6 +415,10 @@
if (resource_type == "item") {
can_be_bag = false;
+ // The default format for <item> is any. If a format attribute is present, that one will
+ // override the default.
+ resource_format = android::ResTable_map::TYPE_ANY;
+
// Items have their type encoded in the type attribute.
if (Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
resource_type = maybe_type.value().to_string();
@@ -481,8 +485,8 @@
out_resource->name.type = item_iter->second.type;
out_resource->name.entry = maybe_name.value().to_string();
- // Only use the implicit format for this type if it wasn't overridden.
- if (!resource_format) {
+ // Only use the implied format of the type when there is no explicit format.
+ if (resource_format == 0u) {
resource_format = item_iter->second.format;
}
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index e3abde6..e60ef66 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -25,7 +25,9 @@
#include "test/Test.h"
#include "xml/XmlPullParser.h"
-using android::StringPiece;
+using ::android::StringPiece;
+using ::testing::Eq;
+using ::testing::NotNull;
namespace aapt {
@@ -791,15 +793,25 @@
}
TEST_F(ResourceParserTest, ParseItemElementWithFormat) {
- std::string input =
- R"EOF(<item name="foo" type="integer" format="float">0.3</item>)EOF";
+ std::string input = R"(<item name="foo" type="integer" format="float">0.3</item>)";
ASSERT_TRUE(TestParse(input));
- BinaryPrimitive* val =
- test::GetValue<BinaryPrimitive>(&table_, "integer/foo");
- ASSERT_NE(nullptr, val);
+ BinaryPrimitive* val = test::GetValue<BinaryPrimitive>(&table_, "integer/foo");
+ ASSERT_THAT(val, NotNull());
+ EXPECT_THAT(val->value.dataType, Eq(android::Res_value::TYPE_FLOAT));
- EXPECT_EQ(uint32_t(android::Res_value::TYPE_FLOAT), val->value.dataType);
+ input = R"(<item name="bar" type="integer" format="fraction">100</item>)";
+ ASSERT_FALSE(TestParse(input));
+}
+
+// An <item> without a format specifier accepts all types of values.
+TEST_F(ResourceParserTest, ParseItemElementWithoutFormat) {
+ std::string input = R"(<item name="foo" type="integer">100%p</item>)";
+ ASSERT_TRUE(TestParse(input));
+
+ BinaryPrimitive* val = test::GetValue<BinaryPrimitive>(&table_, "integer/foo");
+ ASSERT_THAT(val, NotNull());
+ EXPECT_THAT(val->value.dataType, Eq(android::Res_value::TYPE_FRACTION));
}
TEST_F(ResourceParserTest, ParseConfigVaryingItem) {
diff --git a/tools/aapt2/integration-tests/AppOne/res/values/test.xml b/tools/aapt2/integration-tests/AppOne/res/values/test.xml
index 91f8bfd..5104f82 100644
--- a/tools/aapt2/integration-tests/AppOne/res/values/test.xml
+++ b/tools/aapt2/integration-tests/AppOne/res/values/test.xml
@@ -30,6 +30,8 @@
<flag name="weak" value="4" />
</attr>
+ <item name="value_that_allows_any_format" type="integer">-100%p</item>
+
<!-- Override the Widget styleable declared in StaticLibOne.
This should merge the two when built in overlay mode. -->
<declare-styleable name="Widget">
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl b/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl
new file mode 100644
index 0000000..23d0f22
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.net.wifi.hotspot2;
+
+parcelable OsuProvider;
diff --git a/wifi/java/android/net/wifi/hotspot2/OsuProvider.java b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
new file mode 100644
index 0000000..25dcdd8
--- /dev/null
+++ b/wifi/java/android/net/wifi/hotspot2/OsuProvider.java
@@ -0,0 +1,231 @@
+/*
+ * 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.net.wifi.hotspot2;
+
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.net.wifi.WifiSsid;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Contained information for a Hotspot 2.0 OSU (Online Sign-Up provider).
+ *
+ * @hide
+ */
+public final class OsuProvider implements Parcelable {
+ /**
+ * OSU (Online Sign-Up) method: OMA DM (Open Mobile Alliance Device Management).
+ * For more info, refer to Section 8.3 of the Hotspot 2.0 Release 2 Technical Specification.
+ */
+ public static final int METHOD_OMA_DM = 0;
+
+ /**
+ * OSU (Online Sign-Up) method: SOAP XML SPP (Subscription Provisioning Protocol).
+ * For more info, refer to Section 8.4 of the Hotspot 2.0 Release 2 Technical Specification.
+ */
+ public static final int METHOD_SOAP_XML_SPP = 1;
+
+ /**
+ * SSID of the network to connect for service sign-up.
+ */
+ private final WifiSsid mOsuSsid;
+
+ /**
+ * Friendly name of the OSU provider.
+ */
+ private final String mFriendlyName;
+
+ /**
+ * Description of the OSU provider.
+ */
+ private final String mServiceDescription;
+
+ /**
+ * URI to browse to for service sign-up.
+ */
+ private final Uri mServerUri;
+
+ /**
+ * Network Access Identifier used for authenticating with the OSU network when OSEN is used.
+ */
+ private final String mNetworkAccessIdentifier;
+
+ /**
+ * List of OSU (Online Sign-Up) method supported.
+ */
+ private final List<Integer> mMethodList;
+
+ /**
+ * Icon data for the OSU (Online Sign-Up) provider.
+ */
+ private final Icon mIcon;
+
+ public OsuProvider(WifiSsid osuSsid, String friendlyName, String serviceDescription,
+ Uri serverUri, String nai, List<Integer> methodList, Icon icon) {
+ mOsuSsid = osuSsid;
+ mFriendlyName = friendlyName;
+ mServiceDescription = serviceDescription;
+ mServerUri = serverUri;
+ mNetworkAccessIdentifier = nai;
+ if (methodList == null) {
+ mMethodList = new ArrayList<>();
+ } else {
+ mMethodList = new ArrayList<>(methodList);
+ }
+ mIcon = icon;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param source The source to copy from
+ */
+ public OsuProvider(OsuProvider source) {
+ if (source == null) {
+ mOsuSsid = null;
+ mFriendlyName = null;
+ mServiceDescription = null;
+ mServerUri = null;
+ mNetworkAccessIdentifier = null;
+ mMethodList = new ArrayList<>();
+ mIcon = null;
+ return;
+ }
+
+ mOsuSsid = source.mOsuSsid;
+ mFriendlyName = source.mFriendlyName;
+ mServiceDescription = source.mServiceDescription;
+ mServerUri = source.mServerUri;
+ mNetworkAccessIdentifier = source.mNetworkAccessIdentifier;
+ if (source.mMethodList == null) {
+ mMethodList = new ArrayList<>();
+ } else {
+ mMethodList = new ArrayList<>(source.mMethodList);
+ }
+ mIcon = source.mIcon;
+ }
+
+ public WifiSsid getOsuSsid() {
+ return mOsuSsid;
+ }
+
+ public String getFriendlyName() {
+ return mFriendlyName;
+ }
+
+ public String getServiceDescription() {
+ return mServiceDescription;
+ }
+
+ public Uri getServerUri() {
+ return mServerUri;
+ }
+
+ public String getNetworkAccessIdentifier() {
+ return mNetworkAccessIdentifier;
+ }
+
+ public List<Integer> getMethodList() {
+ return Collections.unmodifiableList(mMethodList);
+ }
+
+ public Icon getIcon() {
+ return mIcon;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(mOsuSsid, flags);
+ dest.writeString(mFriendlyName);
+ dest.writeString(mServiceDescription);
+ dest.writeParcelable(mServerUri, flags);
+ dest.writeString(mNetworkAccessIdentifier);
+ dest.writeList(mMethodList);
+ dest.writeParcelable(mIcon, flags);
+ }
+
+ @Override
+ public boolean equals(Object thatObject) {
+ if (this == thatObject) {
+ return true;
+ }
+ if (!(thatObject instanceof OsuProvider)) {
+ return false;
+ }
+ OsuProvider that = (OsuProvider) thatObject;
+ return (mOsuSsid == null ? that.mOsuSsid == null : mOsuSsid.equals(that.mOsuSsid))
+ && TextUtils.equals(mFriendlyName, that.mFriendlyName)
+ && TextUtils.equals(mServiceDescription, that.mServiceDescription)
+ && (mServerUri == null ? that.mServerUri == null
+ : mServerUri.equals(that.mServerUri))
+ && TextUtils.equals(mNetworkAccessIdentifier, that.mNetworkAccessIdentifier)
+ && (mMethodList == null ? that.mMethodList == null
+ : mMethodList.equals(that.mMethodList))
+ && (mIcon == null ? that.mIcon == null : mIcon.sameAs(that.mIcon));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mOsuSsid, mFriendlyName, mServiceDescription, mServerUri,
+ mNetworkAccessIdentifier, mMethodList, mIcon);
+ }
+
+ @Override
+ public String toString() {
+ return "OsuProvider{mOsuSsid=" + mOsuSsid
+ + " mFriendlyName=" + mFriendlyName
+ + " mServiceDescription=" + mServiceDescription
+ + " mServerUri=" + mServerUri
+ + " mNetworkAccessIdentifier=" + mNetworkAccessIdentifier
+ + " mMethodList=" + mMethodList
+ + " mIcon=" + mIcon;
+ }
+
+ public static final Creator<OsuProvider> CREATOR =
+ new Creator<OsuProvider>() {
+ @Override
+ public OsuProvider createFromParcel(Parcel in) {
+ WifiSsid osuSsid = (WifiSsid) in.readParcelable(null);
+ String friendlyName = in.readString();
+ String serviceDescription = in.readString();
+ Uri serverUri = (Uri) in.readParcelable(null);
+ String nai = in.readString();
+ List<Integer> methodList = new ArrayList<>();
+ in.readList(methodList, null);
+ Icon icon = (Icon) in.readParcelable(null);
+ return new OsuProvider(osuSsid, friendlyName, serviceDescription, serverUri,
+ nai, methodList, icon);
+ }
+
+ @Override
+ public OsuProvider[] newArray(int size) {
+ return new OsuProvider[size];
+ }
+ };
+}
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
new file mode 100644
index 0000000..9670bfa
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/hotspot2/OsuProviderTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.net.wifi.hotspot2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.net.wifi.WifiSsid;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Unit tests for {@link android.net.wifi.hotspot2.OsuProvider}.
+ */
+@SmallTest
+public class OsuProviderTest {
+ private static final WifiSsid TEST_SSID =
+ WifiSsid.createFromByteArray("TEST SSID".getBytes(StandardCharsets.UTF_8));
+ private static final String TEST_FRIENDLY_NAME = "Friendly Name";
+ private static final String TEST_SERVICE_DESCRIPTION = "Dummy Service";
+ private static final Uri TEST_SERVER_URI = Uri.parse("https://test.com");
+ private static final String TEST_NAI = "test.access.com";
+ private static final List<Integer> TEST_METHOD_LIST =
+ Arrays.asList(OsuProvider.METHOD_SOAP_XML_SPP);
+ private static final Icon TEST_ICON = Icon.createWithData(new byte[10], 0, 10);
+
+ /**
+ * Verify parcel write and read consistency for the given {@link OsuProvider}.
+ *
+ * @param writeInfo The {@link OsuProvider} to verify
+ * @throws Exception
+ */
+ private static void verifyParcel(OsuProvider writeInfo) throws Exception {
+ Parcel parcel = Parcel.obtain();
+ writeInfo.writeToParcel(parcel, 0);
+
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ OsuProvider readInfo = OsuProvider.CREATOR.createFromParcel(parcel);
+ assertEquals(writeInfo, readInfo);
+ }
+
+ /**
+ * Verify parcel read/write for an OSU provider containing no information.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyParcelWithEmptyProviderInfo() throws Exception {
+ verifyParcel(new OsuProvider(null, null, null, null, null, null, null));
+ }
+
+ /**
+ * Verify parcel read/write for an OSU provider containing full information.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyParcelWithFullProviderInfo() throws Exception {
+ verifyParcel(new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME, TEST_SERVICE_DESCRIPTION,
+ TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON));
+ }
+
+ /**
+ * Verify copy constructor with a null source.
+ * @throws Exception
+ */
+ @Test
+ public void verifyCopyConstructorWithNullSource() throws Exception {
+ OsuProvider expected = new OsuProvider(null, null, null, null, null, null, null);
+ assertEquals(expected, new OsuProvider(null));
+ }
+
+ /**
+ * Verify copy constructor with a valid source.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyCopyConstructorWithValidSource() throws Exception {
+ OsuProvider source = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME, TEST_SERVICE_DESCRIPTION,
+ TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON);
+ assertEquals(source, new OsuProvider(source));
+ }
+
+ /**
+ * Verify getter methods.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyGetters() throws Exception {
+ OsuProvider provider = new OsuProvider(TEST_SSID, TEST_FRIENDLY_NAME,
+ TEST_SERVICE_DESCRIPTION, TEST_SERVER_URI, TEST_NAI, TEST_METHOD_LIST, TEST_ICON);
+ assertTrue(TEST_SSID.equals(provider.getOsuSsid()));
+ assertTrue(TEST_FRIENDLY_NAME.equals(provider.getFriendlyName()));
+ assertTrue(TEST_SERVICE_DESCRIPTION.equals(provider.getServiceDescription()));
+ assertTrue(TEST_SERVER_URI.equals(provider.getServerUri()));
+ assertTrue(TEST_NAI.equals(provider.getNetworkAccessIdentifier()));
+ assertTrue(TEST_METHOD_LIST.equals(provider.getMethodList()));
+ assertTrue(TEST_ICON.sameAs(provider.getIcon()));
+ }
+}