Merge "Add sungsoo@ to OWNERS"
diff --git a/apct-tests/perftests/core/Android.mk b/apct-tests/perftests/core/Android.mk
index 75cb229..b7b87dd 100644
--- a/apct-tests/perftests/core/Android.mk
+++ b/apct-tests/perftests/core/Android.mk
@@ -22,6 +22,8 @@
# Use google-fonts/dancing-script for the performance metrics
LOCAL_ASSET_DIR := $(TOP)/external/google-fonts/dancing-script
+LOCAL_COMPATIBILITY_SUITE += device-tests
+
include $(BUILD_PACKAGE)
include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/cmds/webview_zygote/Android.mk b/cmds/webview_zygote/Android.mk
deleted file mode 100644
index 955e58e..0000000
--- a/cmds/webview_zygote/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := webview_zygote
-
-LOCAL_SRC_FILES := webview_zygote.cpp
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_SHARED_LIBRARIES := \
- libandroid_runtime \
- libbinder \
- liblog \
- libcutils \
- libutils
-
-LOCAL_LDFLAGS_32 := -Wl,--version-script,art/sigchainlib/version-script32.txt -Wl,--export-dynamic
-LOCAL_LDFLAGS_64 := -Wl,--version-script,art/sigchainlib/version-script64.txt -Wl,--export-dynamic
-
-LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
-
-LOCAL_INIT_RC := webview_zygote32.rc
-
-# Always include the 32-bit version of webview_zygote. If the target is 64-bit,
-# also include the 64-bit webview_zygote.
-ifeq ($(TARGET_SUPPORTS_64_BIT_APPS),true)
- LOCAL_INIT_RC += webview_zygote64.rc
-endif
-
-LOCAL_MULTILIB := both
-
-LOCAL_MODULE_STEM_32 := webview_zygote32
-LOCAL_MODULE_STEM_64 := webview_zygote64
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/webview_zygote/webview_zygote.cpp b/cmds/webview_zygote/webview_zygote.cpp
deleted file mode 100644
index 88fee64..0000000
--- a/cmds/webview_zygote/webview_zygote.cpp
+++ /dev/null
@@ -1,76 +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.
- */
-
-
-#define LOG_TAG "WebViewZygote"
-
-#include <sys/prctl.h>
-
-#include <android_runtime/AndroidRuntime.h>
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-class WebViewRuntime : public AndroidRuntime {
-public:
- WebViewRuntime(char* argBlockStart, size_t argBlockSize)
- : AndroidRuntime(argBlockStart, argBlockSize) {}
-
- ~WebViewRuntime() override {}
-
- void onStarted() override {
- // Nothing to do since this is a zygote server.
- }
-
- void onVmCreated(JNIEnv*) override {
- // Nothing to do when the VM is created in the zygote.
- }
-
- void onZygoteInit() override {
- // Called after a new process is forked.
- sp<ProcessState> proc = ProcessState::self();
- proc->startThreadPool();
- }
-
- void onExit(int code) override {
- IPCThreadState::self()->stopProcess();
- AndroidRuntime::onExit(code);
- }
-};
-
-} // namespace android
-
-int main(int argc, char* const argv[]) {
- if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
- LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
- return 12;
- }
-
- size_t argBlockSize = 0;
- for (int i = 0; i < argc; ++i) {
- argBlockSize += strlen(argv[i]) + 1;
- }
-
- android::WebViewRuntime runtime(argv[0], argBlockSize);
- runtime.addOption("-Xzygote");
-
- android::Vector<android::String8> args;
- runtime.start("com.android.internal.os.WebViewZygoteInit", args, /*zygote=*/ true);
-}
diff --git a/cmds/webview_zygote/webview_zygote32.rc b/cmds/webview_zygote/webview_zygote32.rc
deleted file mode 100644
index b7decc8..0000000
--- a/cmds/webview_zygote/webview_zygote32.rc
+++ /dev/null
@@ -1,22 +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.
-#
-
-service webview_zygote32 /system/bin/webview_zygote32
- user webview_zygote
- socket webview_zygote stream 660 webview_zygote system
-
-on property:init.svc.zygote=stopped
- stop webview_zygote32
diff --git a/cmds/webview_zygote/webview_zygote64.rc b/cmds/webview_zygote/webview_zygote64.rc
deleted file mode 100644
index 2935b28..0000000
--- a/cmds/webview_zygote/webview_zygote64.rc
+++ /dev/null
@@ -1,22 +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.
-#
-
-service webview_zygote64 /system/bin/webview_zygote64
- user webview_zygote
- socket webview_zygote stream 660 webview_zygote system
-
-on property:init.svc.zygote=stopped
- stop webview_zygote64
diff --git a/core/java/android/hardware/radio/OWNERS b/core/java/android/hardware/radio/OWNERS
new file mode 100644
index 0000000..ea4421e
--- /dev/null
+++ b/core/java/android/hardware/radio/OWNERS
@@ -0,0 +1,2 @@
+twasilczyk@google.com
+randolphs@google.com
diff --git a/core/java/android/util/RecurrenceRule.java b/core/java/android/util/RecurrenceRule.java
index 1fe638d..cd8b097 100644
--- a/core/java/android/util/RecurrenceRule.java
+++ b/core/java/android/util/RecurrenceRule.java
@@ -41,7 +41,7 @@
*/
public class RecurrenceRule implements Parcelable {
private static final String TAG = "RecurrenceRule";
- private static final boolean DEBUG = true;
+ private static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
private static final int VERSION_INIT = 0;
@@ -192,7 +192,7 @@
public RecurringIterator() {
final ZonedDateTime anchor = (end != null) ? end
: ZonedDateTime.now(sClock).withZoneSameInstant(start.getZone());
- if (DEBUG) Log.d(TAG, "Resolving using anchor " + anchor);
+ if (LOGD) Log.d(TAG, "Resolving using anchor " + anchor);
updateCycle();
@@ -231,7 +231,7 @@
@Override
public Pair<ZonedDateTime, ZonedDateTime> next() {
- if (DEBUG) Log.d(TAG, "Cycle " + i + " from " + cycleStart + " to " + cycleEnd);
+ if (LOGD) Log.d(TAG, "Cycle " + i + " from " + cycleStart + " to " + cycleEnd);
Pair<ZonedDateTime, ZonedDateTime> p = new Pair<>(cycleStart, cycleEnd);
i--;
updateCycle();
diff --git a/core/java/android/util/apk/ApkSigningBlockUtils.java b/core/java/android/util/apk/ApkSigningBlockUtils.java
index 4146f6f..40db758 100644
--- a/core/java/android/util/apk/ApkSigningBlockUtils.java
+++ b/core/java/android/util/apk/ApkSigningBlockUtils.java
@@ -373,9 +373,9 @@
static final int SIGNATURE_ECDSA_WITH_SHA256 = 0x0201;
static final int SIGNATURE_ECDSA_WITH_SHA512 = 0x0202;
static final int SIGNATURE_DSA_WITH_SHA256 = 0x0301;
- static final int SIGNATURE_VERITY_RSA_PKCS1_V1_5_WITH_SHA256 = 0x0401;
- static final int SIGNATURE_VERITY_ECDSA_WITH_SHA256 = 0x0403;
- static final int SIGNATURE_VERITY_DSA_WITH_SHA256 = 0x0405;
+ static final int SIGNATURE_VERITY_RSA_PKCS1_V1_5_WITH_SHA256 = 0x0411;
+ static final int SIGNATURE_VERITY_ECDSA_WITH_SHA256 = 0x0413;
+ static final int SIGNATURE_VERITY_DSA_WITH_SHA256 = 0x0415;
static final int CONTENT_DIGEST_CHUNKED_SHA256 = 1;
static final int CONTENT_DIGEST_CHUNKED_SHA512 = 2;
@@ -754,9 +754,6 @@
md.update(buffer);
}
}
-
- @Override
- public void finish() {}
}
}
diff --git a/core/java/android/util/apk/ApkVerityBuilder.java b/core/java/android/util/apk/ApkVerityBuilder.java
index a3eeb27..7b89967 100644
--- a/core/java/android/util/apk/ApkVerityBuilder.java
+++ b/core/java/android/util/apk/ApkVerityBuilder.java
@@ -207,14 +207,10 @@
}
}
- /** Finish the current digestion if any. */
- @Override
- public void finish() throws DigestException {
- if (mBytesDigestedSinceReset == 0) {
- return;
+ public void assertEmptyBuffer() throws DigestException {
+ if (mBytesDigestedSinceReset != 0) {
+ throw new IllegalStateException("Buffer is not empty: " + mBytesDigestedSinceReset);
}
- mMd.digest(mDigestBuffer, 0, mDigestBuffer.length);
- mOutput.put(mDigestBuffer);
}
private void fillUpLastOutputChunk() {
@@ -279,9 +275,15 @@
new MemoryMappedFileDataSource(apk.getFD(), offsetAfterEocdCdOffsetField,
apk.length() - offsetAfterEocdCdOffsetField),
MMAP_REGION_SIZE_BYTES);
- digester.finish();
- // 5. Fill up the rest of buffer with 0s.
+ // 5. Pad 0s up to the nearest 4096-byte block before hashing.
+ int lastIncompleteChunkSize = (int) (apk.length() % CHUNK_SIZE_BYTES);
+ if (lastIncompleteChunkSize != 0) {
+ digester.consume(ByteBuffer.allocate(CHUNK_SIZE_BYTES - lastIncompleteChunkSize));
+ }
+ digester.assertEmptyBuffer();
+
+ // 6. Fill up the rest of buffer with 0s.
digester.fillUpLastOutputChunk();
}
@@ -300,8 +302,7 @@
DataSource source = new ByteBufferDataSource(inputBuffer);
BufferedDigester digester = new BufferedDigester(salt, outputBuffer);
consumeByChunk(digester, source, CHUNK_SIZE_BYTES);
- digester.finish();
-
+ digester.assertEmptyBuffer();
digester.fillUpLastOutputChunk();
}
@@ -309,7 +310,7 @@
byte[] rootHash = new byte[DIGEST_SIZE_BYTES];
BufferedDigester digester = new BufferedDigester(salt, ByteBuffer.wrap(rootHash));
digester.consume(slice(output, 0, CHUNK_SIZE_BYTES));
- digester.finish();
+ digester.assertEmptyBuffer();
return rootHash;
}
diff --git a/core/java/android/util/apk/DataDigester.java b/core/java/android/util/apk/DataDigester.java
index 278be80..18d1dff 100644
--- a/core/java/android/util/apk/DataDigester.java
+++ b/core/java/android/util/apk/DataDigester.java
@@ -22,7 +22,4 @@
interface DataDigester {
/** Consumes the {@link ByteBuffer}. */
void consume(ByteBuffer buffer) throws DigestException;
-
- /** Finishes the digestion. Must be called after the last {@link #consume(ByteBuffer)}. */
- void finish() throws DigestException;
}
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index db60ad8..63fbef3 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -20,28 +20,22 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.os.Build;
-import android.os.SystemService;
+import android.os.ChildZygoteProcess;
+import android.os.Process;
import android.os.ZygoteProcess;
import android.text.TextUtils;
-import android.util.AndroidRuntimeException;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import java.io.File;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
-import java.util.concurrent.TimeoutException;
/** @hide */
public class WebViewZygote {
private static final String LOGTAG = "WebViewZygote";
- private static final String WEBVIEW_ZYGOTE_SERVICE_32 = "webview_zygote32";
- private static final String WEBVIEW_ZYGOTE_SERVICE_64 = "webview_zygote64";
- private static final String WEBVIEW_ZYGOTE_SOCKET = "webview_zygote";
-
/**
* Lock object that protects all other static members.
*/
@@ -52,14 +46,7 @@
* zygote is not running or is not connected.
*/
@GuardedBy("sLock")
- private static ZygoteProcess sZygote;
-
- /**
- * Variable that allows us to determine whether the WebView zygote Service has already been
- * started.
- */
- @GuardedBy("sLock")
- private static boolean sStartedService = false;
+ private static ChildZygoteProcess sZygote;
/**
* Information about the selected WebView package. This is set from #onWebViewProviderChanged().
@@ -85,7 +72,7 @@
synchronized (sLock) {
if (sZygote != null) return sZygote;
- waitForServiceStartAndConnect();
+ connectToZygoteIfNeededLocked();
return sZygote;
}
}
@@ -107,21 +94,13 @@
sMultiprocessEnabled = enabled;
// When toggling between multi-process being on/off, start or stop the
- // service. If it is enabled and the zygote is not yet started, bring up the service.
- // Otherwise, bring down the service. The name may be null if the package
- // information has not yet been resolved.
- final String serviceName = getServiceNameLocked();
- if (serviceName == null) return;
-
+ // zygote. If it is enabled and the zygote is not yet started, launch it.
+ // Otherwise, kill it. The name may be null if the package information has
+ // not yet been resolved.
if (enabled) {
- if (!sStartedService) {
- SystemService.start(serviceName);
- sStartedService = true;
- }
+ connectToZygoteIfNeededLocked();
} else {
- SystemService.stop(serviceName);
- sStartedService = false;
- sZygote = null;
+ stopZygoteLocked();
}
}
}
@@ -137,53 +116,21 @@
return;
}
- final String serviceName = getServiceNameLocked();
- sZygote = null;
-
- // The service may enter the RUNNING state before it opens the socket,
- // so connectToZygoteIfNeededLocked() may still fail.
- if (SystemService.isStopped(serviceName)) {
- SystemService.start(serviceName);
- } else {
- SystemService.restart(serviceName);
- }
- sStartedService = true;
- }
- }
-
- private static void waitForServiceStartAndConnect() {
- if (!sStartedService) {
- throw new AndroidRuntimeException("Tried waiting for the WebView Zygote Service to " +
- "start running without first starting the service.");
- }
-
- String serviceName;
- synchronized (sLock) {
- serviceName = getServiceNameLocked();
- }
- try {
- SystemService.waitForState(serviceName, SystemService.State.RUNNING, 5000);
- } catch (TimeoutException e) {
- Log.e(LOGTAG, "Timed out waiting for " + serviceName);
- return;
- }
-
- synchronized (sLock) {
- connectToZygoteIfNeededLocked();
+ stopZygoteLocked();
}
}
@GuardedBy("sLock")
- private static String getServiceNameLocked() {
- if (sPackage == null)
- return null;
-
- if (Arrays.asList(Build.SUPPORTED_64_BIT_ABIS).contains(
- sPackage.applicationInfo.primaryCpuAbi)) {
- return WEBVIEW_ZYGOTE_SERVICE_64;
+ private static void stopZygoteLocked() {
+ if (sZygote != null) {
+ // Close the connection and kill the zygote process. This will not cause
+ // child processes to be killed by itself. But if this is called in response to
+ // setMultiprocessEnabled() or onWebViewProviderChanged(), the WebViewUpdater
+ // will kill all processes that depend on the WebView package.
+ sZygote.close();
+ Process.killProcess(sZygote.getPid());
+ sZygote = null;
}
-
- return WEBVIEW_ZYGOTE_SERVICE_32;
}
@GuardedBy("sLock")
@@ -197,14 +144,17 @@
return;
}
- final String serviceName = getServiceNameLocked();
- if (!SystemService.isRunning(serviceName)) {
- Log.e(LOGTAG, serviceName + " is not running");
- return;
- }
-
try {
- sZygote = new ZygoteProcess(WEBVIEW_ZYGOTE_SOCKET, null);
+ sZygote = Process.zygoteProcess.startChildZygote(
+ "com.android.internal.os.WebViewZygoteInit",
+ "webview_zygote",
+ Process.WEBVIEW_ZYGOTE_UID,
+ Process.WEBVIEW_ZYGOTE_UID,
+ null, // gids
+ 0, // runtimeFlags
+ "webview_zygote", // seInfo
+ sPackage.applicationInfo.primaryCpuAbi, // abi
+ null); // instructionSet
// All the work below is usually done by LoadedApk, but the zygote can't talk to
// PackageManager or construct a LoadedApk since it's single-threaded pre-fork, so
@@ -226,14 +176,14 @@
final String cacheKey = (zipPaths.size() == 1) ? zipPaths.get(0) :
TextUtils.join(File.pathSeparator, zipPaths);
- ZygoteProcess.waitForConnectionToZygote(WEBVIEW_ZYGOTE_SOCKET);
+ ZygoteProcess.waitForConnectionToZygote(sZygote.getPrimarySocketAddress());
Log.d(LOGTAG, "Preloading package " + zip + " " + librarySearchPath);
sZygote.preloadPackageForAbi(zip, librarySearchPath, cacheKey,
Build.SUPPORTED_ABIS[0]);
} catch (Exception e) {
- Log.e(LOGTAG, "Error connecting to " + serviceName, e);
- sZygote = null;
+ Log.e(LOGTAG, "Error connecting to webview zygote", e);
+ stopZygoteLocked();
}
}
}
diff --git a/core/java/com/android/internal/os/WebViewZygoteInit.java b/core/java/com/android/internal/os/WebViewZygoteInit.java
index b38c851..32b580c 100644
--- a/core/java/com/android/internal/os/WebViewZygoteInit.java
+++ b/core/java/com/android/internal/os/WebViewZygoteInit.java
@@ -18,9 +18,11 @@
import android.app.ApplicationLoaders;
import android.net.LocalSocket;
+import android.net.LocalServerSocket;
import android.os.Build;
import android.system.ErrnoException;
import android.system.Os;
+import android.system.OsConstants;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.WebViewFactory;
@@ -118,18 +120,35 @@
}
public static void main(String argv[]) {
- sServer = new WebViewZygoteServer();
+ Log.i(TAG, "Starting WebViewZygoteInit");
- // Zygote goes into its own process group.
- try {
- Os.setpgid(0, 0);
- } catch (ErrnoException ex) {
- throw new RuntimeException("Failed to setpgid(0,0)", ex);
+ String socketName = null;
+ for (String arg : argv) {
+ Log.i(TAG, arg);
+ if (arg.startsWith(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG)) {
+ socketName = arg.substring(Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG.length());
+ }
}
+ if (socketName == null) {
+ throw new RuntimeException("No " + Zygote.CHILD_ZYGOTE_SOCKET_NAME_ARG + " specified");
+ }
+
+ try {
+ Os.prctl(OsConstants.PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ } catch (ErrnoException ex) {
+ throw new RuntimeException("Failed to set PR_SET_NO_NEW_PRIVS", ex);
+ }
+
+ sServer = new WebViewZygoteServer();
final Runnable caller;
try {
- sServer.registerServerSocketFromEnv("webview_zygote");
+ sServer.registerServerSocketAtAbstractName(socketName);
+
+ // Add the abstract socket to the FD whitelist so that the native zygote code
+ // can properly detach it after forking.
+ Zygote.nativeAllowFileAcrossFork("ABSTRACT/" + socketName);
+
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
caller = sServer.runSelectLoop(TextUtils.join(",", Build.SUPPORTED_ABIS));
diff --git a/core/tests/BroadcastRadioTests/OWNERS b/core/tests/BroadcastRadioTests/OWNERS
new file mode 100644
index 0000000..ea4421e
--- /dev/null
+++ b/core/tests/BroadcastRadioTests/OWNERS
@@ -0,0 +1,2 @@
+twasilczyk@google.com
+randolphs@google.com
diff --git a/media/java/android/media/MediaBrowser2.java b/media/java/android/media/MediaBrowser2.java
index 32d3162..231a4a5 100644
--- a/media/java/android/media/MediaBrowser2.java
+++ b/media/java/android/media/MediaBrowser2.java
@@ -88,14 +88,15 @@
public void onItemLoaded(@NonNull String mediaId, @Nullable MediaItem2 result) { }
/**
- * Called when there's change in the search result.
+ * Called when there's change in the search result requested by the previous
+ * {@link MediaBrowser2#search(String, Bundle)}.
*
* @param query search query that you've specified with {@link #search(String, Bundle)}
- * @param extras extra bundle that you've specified with {@link #search(String, Bundle)}
- * @param totalItemCount The total item count for the search result
+ * @param extras extra bundle
+ * @param itemCount The item count for the search result
*/
public void onSearchResultChanged(@NonNull String query, @Nullable Bundle extras,
- int totalItemCount) { }
+ int itemCount) { }
/**
* Called when the search result has been returned by the library service for the previous
@@ -189,10 +190,9 @@
}
/**
- * Send a search request to the library service. When there's a change,
- * {@link BrowserCallback#onSearchResultChanged(String, Bundle, int)} will be called with the
- * bundle that you've specified. You should call
- * {@link #getSearchResult(String, int, int, Bundle)} to get the actual search result.
+ * Send a search request to the library service. When the search result is changed,
+ * {@link BrowserCallback#onSearchResultChanged(String, Bundle, int)} will be called. You should
+ * call {@link #getSearchResult(String, int, int, Bundle)} to get the actual search result.
*
* @param query search query. Should not be an empty string.
* @param extras extra bundle
diff --git a/media/java/android/media/MediaController2.java b/media/java/android/media/MediaController2.java
index bd6c7e6..bfd1fd4 100644
--- a/media/java/android/media/MediaController2.java
+++ b/media/java/android/media/MediaController2.java
@@ -570,14 +570,14 @@
}
/**
- * Rate the current content. This will cause the rating to be set for
- * the current user. The Rating type must match the type returned by
- * {@link #getRatingType()}.
+ * Rate the media. This will cause the rating to be set for the current user.
+ * The Rating type must match the type returned by {@link #getRatingType()}.
*
- * @param rating The rating to set for the current content
+ * @param mediaId The id of the media
+ * @param rating The rating to set
*/
- public void setRating(Rating2 rating) {
- mProvider.setRating_impl(rating);
+ public void setRating(String mediaId, Rating2 rating) {
+ mProvider.setRating_impl(mediaId, rating);
}
/**
diff --git a/media/java/android/media/MediaLibraryService2.java b/media/java/android/media/MediaLibraryService2.java
index 7a05d3c..95d83ee 100644
--- a/media/java/android/media/MediaLibraryService2.java
+++ b/media/java/android/media/MediaLibraryService2.java
@@ -99,6 +99,19 @@
public void notifyChildrenChanged(@NonNull String parentId, @Nullable Bundle extras) {
mProvider.notifyChildrenChanged_impl(parentId, extras);
}
+
+ /**
+ * Notify controller about change in the search result.
+ *
+ * @param controller controller to notify
+ * @param query previously sent search query from the controller.
+ * @param extras extra bundle
+ * @param itemCount the number of items that have been found in the search.
+ */
+ public void notifySearchResultChanged(@NonNull ControllerInfo controller,
+ @NonNull String query, @NonNull Bundle extras, int itemCount) {
+ mProvider.notifySearchResultChanged_impl(controller, query, extras, itemCount);
+ }
}
/**
diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java
index 943b827..0258dca 100644
--- a/media/java/android/media/MediaSession2.java
+++ b/media/java/android/media/MediaSession2.java
@@ -452,13 +452,15 @@
}
/**
- * Called when a controller set rating on the currently playing contents by
- * {@link MediaController2#setRating(Rating2)}.
+ * Called when a controller set rating of a media item through
+ * {@link MediaController2#setRating(String, Rating2)}.
*
* @param controller controller information
+ * @param mediaId media id from the controller
* @param rating new rating from the controller
*/
- public void onSetRating(@NonNull ControllerInfo controller, @NonNull Rating2 rating) { }
+ public void onSetRating(@NonNull ControllerInfo controller, @NonNull String mediaId,
+ @NonNull Rating2 rating) { }
/**
* Called when a controller sent a custom command through
diff --git a/media/java/android/media/update/MediaBrowser2Provider.java b/media/java/android/media/update/MediaBrowser2Provider.java
index f2e7313..eda4c7c 100644
--- a/media/java/android/media/update/MediaBrowser2Provider.java
+++ b/media/java/android/media/update/MediaBrowser2Provider.java
@@ -24,11 +24,11 @@
public interface MediaBrowser2Provider extends MediaController2Provider {
void getLibraryRoot_impl(Bundle rootHints);
- void subscribe_impl(String parentId, Bundle options);
- void unsubscribe_impl(String parentId, Bundle options);
+ void subscribe_impl(String parentId, Bundle extras);
+ void unsubscribe_impl(String parentId, Bundle extras);
void getItem_impl(String mediaId);
void getChildren_impl(String parentId, int page, int pageSize, Bundle extras);
- void search_impl(String query, Bundle options);
+ void search_impl(String query, Bundle extras);
void getSearchResult_impl(String query, int page, int pageSize, Bundle extras);
}
diff --git a/media/java/android/media/update/MediaController2Provider.java b/media/java/android/media/update/MediaController2Provider.java
index c492d307..738bd0c 100644
--- a/media/java/android/media/update/MediaController2Provider.java
+++ b/media/java/android/media/update/MediaController2Provider.java
@@ -56,7 +56,7 @@
void playFromUri_impl(Uri uri, Bundle extras);
void playFromMediaId_impl(String mediaId, Bundle extras);
- void setRating_impl(Rating2 rating);
+ void setRating_impl(String mediaId, Rating2 rating);
void sendCustomCommand_impl(Command command, Bundle args, ResultReceiver cb);
List<MediaItem2> getPlaylist_impl();
diff --git a/media/java/android/media/update/MediaLibraryService2Provider.java b/media/java/android/media/update/MediaLibraryService2Provider.java
index 923551a..d837833 100644
--- a/media/java/android/media/update/MediaLibraryService2Provider.java
+++ b/media/java/android/media/update/MediaLibraryService2Provider.java
@@ -30,8 +30,10 @@
// Nothing new for now
interface MediaLibrarySessionProvider extends MediaSession2Provider {
- void notifyChildrenChanged_impl(ControllerInfo controller, String parentId, Bundle options);
- void notifyChildrenChanged_impl(String parentId, Bundle options);
+ void notifyChildrenChanged_impl(ControllerInfo controller, String parentId, Bundle extras);
+ void notifyChildrenChanged_impl(String parentId, Bundle extras);
+ void notifySearchResultChanged_impl(ControllerInfo controller, String query, Bundle extras,
+ int itemCount);
}
interface LibraryRootProvider {
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_bg.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_bg.xml
deleted file mode 100644
index 4a77af9..0000000
--- a/packages/SystemUI/res/drawable/fingerprint_dialog_bg.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/fingerprint_dialog_bg_color" />
- <corners android:radius="1dp"
- android:topLeftRadius="16dp"
- android:topRightRadius="16dp"
- android:bottomLeftRadius="0dp"
- android:bottomRightRadius="0dp"/>
-</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/fingerprint_dialog.xml b/packages/SystemUI/res/layout/fingerprint_dialog.xml
index 161f13f..f02c0ba 100644
--- a/packages/SystemUI/res/layout/fingerprint_dialog.xml
+++ b/packages/SystemUI/res/layout/fingerprint_dialog.xml
@@ -35,131 +35,105 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:elevation="2dp"
- android:background="@drawable/fingerprint_dialog_bg">
+ android:background="@color/fingerprint_dialog_bg_color">
- <RelativeLayout
+ <TextView
+ android:id="@+id/title"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:elevation="2dp">
+ android:layout_marginEnd="24dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginTop="24dp"
+ android:gravity="center"
+ android:textSize="20sp"
+ android:maxLines="1"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:textColor="@color/fingerprint_dialog_text_dark_color"/>
- <ImageView
- android:id="@+id/icon"
- android:layout_width="@dimen/fingerprint_dialog_icon_size"
- android:layout_height="@dimen/fingerprint_dialog_icon_size"
- android:layout_marginTop="16dp"
- android:layout_marginStart="16dp"
- android:scaleType="centerInside" />
-
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@+id/icon"
- android:layout_marginEnd="16dp"
- android:layout_marginStart="16dp"
- android:layout_marginTop="16dp"
- android:textSize="20sp"
- android:maxLines="1"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:marqueeRepeatLimit="marquee_forever"
- android:textColor="@color/fingerprint_dialog_text_color"/>
-
- <TextView
- android:id="@+id/subtitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@+id/icon"
- android:layout_below="@+id/title"
- android:layout_marginEnd="16dp"
- android:layout_marginStart="16dp"
- android:layout_marginTop="4dp"
- android:textSize="12sp"
- android:maxLines="2"
- android:textColor="@color/fingerprint_dialog_text_color"/>
-
- </RelativeLayout>
+ <TextView
+ android:id="@+id/subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="12dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
+ android:gravity="center_horizontal"
+ android:textSize="14sp"
+ android:maxLines="1"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:textColor="@color/fingerprint_dialog_text_light_color"/>
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginEnd="16dp"
- android:layout_marginStart="16dp"
- android:paddingTop="16dp"
- android:paddingBottom="20dp"
+ android:layout_marginEnd="24dp"
+ android:layout_marginStart="24dp"
+ android:paddingTop="24dp"
android:textSize="16sp"
android:maxLines="4"
- android:textColor="@color/fingerprint_dialog_text_color"/>
+ android:textColor="@color/fingerprint_dialog_text_dark_color"/>
<ImageView
android:id="@+id/fingerprint_icon"
android:layout_width="@dimen/fingerprint_dialog_fp_icon_size"
android:layout_height="@dimen/fingerprint_dialog_fp_icon_size"
android:layout_gravity="center_horizontal"
- android:scaleType="centerInside"
- android:contentDescription="@string/accessibility_fingerprint_dialog_fingerprint_icon"
- android:src="@drawable/fingerprint_icon"/>
+ android:layout_marginTop="32dp"
+ android:scaleType="fitXY"
+ android:contentDescription="@string/accessibility_fingerprint_dialog_fingerprint_icon" />
<TextView
android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginEnd = "16dp"
- android:layout_marginStart="16dp"
+ android:layout_marginEnd="24dp"
+ android:layout_marginStart="24dp"
android:paddingTop="16dp"
- android:paddingBottom="60dp"
+ android:paddingBottom="24dp"
android:textSize="12sp"
- android:visibility="invisible"
android:gravity="center_horizontal"
android:accessibilityLiveRegion="polite"
+ android:text="@string/fingerprint_dialog_touch_sensor"
android:contentDescription="@string/accessibility_fingerprint_dialog_help_area"
- android:textColor="@color/fingerprint_error_message_color"/>
+ android:textColor="@color/fingerprint_dialog_text_light_color"/>
- <LinearLayout android:id="@+id/buttonPanel"
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="54dip"
- android:orientation="vertical" >
- <LinearLayout
- style="?android:attr/buttonBarStyle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:paddingTop="4dip"
- android:paddingStart="2dip"
- android:paddingEnd="2dip"
- android:measureWithLargestChild="true">
- <LinearLayout android:id="@+id/leftSpacer"
- android:layout_weight="0.25"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:visibility="gone" />
- <!-- Positive Button -->
- <Button android:id="@+id/button1"
- android:layout_width="0dip"
- android:layout_gravity="start"
- android:layout_weight="1"
- style="?android:attr/buttonBarButtonStyle"
- android:maxLines="2"
- android:layout_height="wrap_content"/>
- <!-- Negative Button -->
- <Button android:id="@+id/button2"
- android:layout_width="0dip"
- android:layout_gravity="end"
- android:layout_weight="1"
- style="?android:attr/buttonBarButtonStyle"
- android:maxLines="2"
- android:layout_height="wrap_content" />
- <LinearLayout android:id="@+id/rightSpacer"
- android:layout_width="0dip"
- android:layout_weight="0.25"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:visibility="gone" />
- </LinearLayout>
+ android:layout_height="72dip"
+ android:paddingTop="16dp"
+ android:layout_gravity="center_vertical"
+ style="?android:attr/buttonBarStyle"
+ android:orientation="horizontal"
+ android:measureWithLargestChild="true">
+ <Space android:id="@+id/leftSpacer"
+ android:layout_width="24dp"
+ android:layout_height="match_parent"
+ android:visibility="visible" />
+ <!-- Negative Button -->
+ <Button android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+ android:layout_marginStart="-12dp"
+ android:gravity="start|center_vertical"
+ android:maxLines="2" />
+ <!-- Positive Button -->
+ <Button android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+ android:layout_marginEnd="12dp"
+ android:maxLines="2" />
+ <Space android:id="@+id/rightSpacer"
+ android:layout_width="24dip"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
</LinearLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index c054d16..e2a94df 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -161,9 +161,11 @@
<!-- Fingerprint dialog colors -->
<color name="fingerprint_dialog_bg_color">#f4ffffff</color> <!-- 96% white -->
- <color name="fingerprint_dialog_text_color">#ff424242</color> <!-- gray 800-->
+ <color name="fingerprint_dialog_text_dark_color">#ff212121</color>
+ <color name="fingerprint_dialog_text_light_color">#ff757575</color>
<color name="fingerprint_dialog_dim_color">#80000000</color> <!-- 50% black -->
- <color name="fingerprint_error_message_color">#ff5722</color>
+ <color name="fingerprint_dialog_error_message_color">#ffff5722</color>
+ <color name="fingerprint_dialog_fingerprint_color">#ff009688</color>
<!-- Logout button -->
<color name="logout_button_bg_color">#ccffffff</color>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3ff553e..e679fcd 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -895,7 +895,7 @@
<dimen name="smart_reply_button_font_size">14sp</dimen>
<dimen name="smart_reply_button_line_spacing_extra">6sp</dimen> <!-- Total line height 20sp. -->
- <dimen name="fingerprint_dialog_icon_size">44dp</dimen>
+ <!-- Fingerprint Dialog values -->
<dimen name="fingerprint_dialog_fp_icon_size">60dp</dimen>
<dimen name="fingerprint_dialog_animation_translation_offset">350dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8c59e75..0b5b7bd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -259,6 +259,8 @@
<!-- Button name for "Cancel". [CHAR LIMIT=NONE] -->
<string name="cancel">Cancel</string>
+ <!-- Message shown when the system-provided fingerprint dialog is shown, asking for authentication -->
+ <string name="fingerprint_dialog_touch_sensor">Touch the fingerprint sensor</string>
<!-- Content description of the fingerprint icon when the system-provided fingerprint dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_fingerprint_dialog_fingerprint_icon">Fingerprint icon</string>
<!-- Content description of the application icon when the system-provided fingerprint dialog is showing, for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
index 262c71a..1d43b1d 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
@@ -211,7 +211,7 @@
}
private void handleClearMessage() {
- mDialogView.clearMessage();
+ mDialogView.resetMessage();
}
private void handleUserCanceled() {
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
index 9779937..e828b2c 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
@@ -16,17 +16,18 @@
package com.android.systemui.fingerprint;
-import android.app.ActivityManager;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.pm.ActivityInfo;
+import android.graphics.Color;
import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.fingerprint.FingerprintDialog;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -41,8 +42,6 @@
import com.android.systemui.Interpolators;
import com.android.systemui.R;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.PackageManagerWrapper;
/**
* This class loads the view for the system-provided dialog. The view consists of:
@@ -55,28 +54,39 @@
private static final int ANIMATION_DURATION = 250; // ms
+ private static final int STATE_NONE = 0;
+ private static final int STATE_FINGERPRINT = 1;
+ private static final int STATE_FINGERPRINT_ERROR = 2;
+ private static final int STATE_FINGERPRINT_AUTHENTICATED = 3;
+
private final IBinder mWindowToken = new Binder();
- private final ActivityManagerWrapper mActivityManagerWrapper;
- private final PackageManagerWrapper mPackageManageWrapper;
private final Interpolator mLinearOutSlowIn;
private final Interpolator mFastOutLinearIn;
private final float mAnimationTranslationOffset;
+ private final int mErrorTextColor;
+ private final int mTextColor;
+ private final int mFingerprintColor;
private ViewGroup mLayout;
private final TextView mErrorText;
private Handler mHandler;
private Bundle mBundle;
private final LinearLayout mDialog;
+ private int mLastState;
public FingerprintDialogView(Context context, Handler handler) {
super(context);
mHandler = handler;
- mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
- mPackageManageWrapper = PackageManagerWrapper.getInstance();
mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
mFastOutLinearIn = Interpolators.FAST_OUT_LINEAR_IN;
mAnimationTranslationOffset = getResources()
.getDimension(R.dimen.fingerprint_dialog_animation_translation_offset);
+ mErrorTextColor = Color.parseColor(
+ getResources().getString(R.color.fingerprint_dialog_error_message_color));
+ mTextColor = Color.parseColor(
+ getResources().getString(R.color.fingerprint_dialog_text_light_color));
+ mFingerprintColor = Color.parseColor(
+ getResources().getString(R.color.fingerprint_dialog_fingerprint_color));
// Create the dialog
LayoutInflater factory = LayoutInflater.from(getContext());
@@ -112,7 +122,7 @@
space.setClickable(true);
space.setOnTouchListener((View view, MotionEvent event) -> {
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_HIDE_DIALOG, true /* userCanceled*/)
+ mHandler.obtainMessage(FingerprintDialogImpl.MSG_HIDE_DIALOG, true /* userCanceled */)
.sendToTarget();
return true;
});
@@ -137,16 +147,16 @@
final TextView subtitle = mLayout.findViewById(R.id.subtitle);
final TextView description = mLayout.findViewById(R.id.description);
final Button negative = mLayout.findViewById(R.id.button2);
- final ImageView image = mLayout.findViewById(R.id.icon);
final Button positive = mLayout.findViewById(R.id.button1);
- final ImageView fingerprint_icon = mLayout.findViewById(R.id.fingerprint_icon);
+
+ mLastState = STATE_NONE;
+ updateFingerprintIcon(STATE_FINGERPRINT);
title.setText(mBundle.getCharSequence(FingerprintDialog.KEY_TITLE));
title.setSelected(true);
subtitle.setText(mBundle.getCharSequence(FingerprintDialog.KEY_SUBTITLE));
description.setText(mBundle.getCharSequence(FingerprintDialog.KEY_DESCRIPTION));
negative.setText(mBundle.getCharSequence(FingerprintDialog.KEY_NEGATIVE_TEXT));
- setAppIcon(image);
final CharSequence positiveText =
mBundle.getCharSequence(FingerprintDialog.KEY_POSITIVE_TEXT);
@@ -183,39 +193,75 @@
mBundle = bundle;
}
- protected void clearMessage() {
- mErrorText.setVisibility(View.INVISIBLE);
+ // Clears the temporary message and shows the help message.
+ protected void resetMessage() {
+ updateFingerprintIcon(STATE_FINGERPRINT);
+ mErrorText.setText(R.string.fingerprint_dialog_touch_sensor);
+ mErrorText.setTextColor(mTextColor);
}
- private void showMessage(String message) {
+ // Shows an error/help message
+ private void showTemporaryMessage(String message) {
mHandler.removeMessages(FingerprintDialogImpl.MSG_CLEAR_MESSAGE);
+ updateFingerprintIcon(STATE_FINGERPRINT_ERROR);
mErrorText.setText(message);
+ mErrorText.setTextColor(mErrorTextColor);
mErrorText.setContentDescription(message);
- mErrorText.setVisibility(View.VISIBLE);
mHandler.sendMessageDelayed(mHandler.obtainMessage(FingerprintDialogImpl.MSG_CLEAR_MESSAGE),
FingerprintDialog.HIDE_DIALOG_DELAY);
}
public void showHelpMessage(String message) {
- showMessage(message);
+ showTemporaryMessage(message);
}
public void showErrorMessage(String error) {
- showMessage(error);
+ showTemporaryMessage(error);
mHandler.sendMessageDelayed(mHandler.obtainMessage(FingerprintDialogImpl.MSG_HIDE_DIALOG,
false /* userCanceled */), FingerprintDialog.HIDE_DIALOG_DELAY);
}
- private void setAppIcon(ImageView image) {
- final ActivityManager.RunningTaskInfo taskInfo = mActivityManagerWrapper.getRunningTask();
- final ComponentName cn = taskInfo.topActivity;
- final int userId = mActivityManagerWrapper.getCurrentUserId();
- final ActivityInfo activityInfo = mPackageManageWrapper.getActivityInfo(cn, userId);
- image.setImageDrawable(mActivityManagerWrapper.getBadgedActivityIcon(activityInfo, userId));
- image.setContentDescription(
- getResources().getString(R.string.accessibility_fingerprint_dialog_app_icon)
- + " "
- + mActivityManagerWrapper.getBadgedActivityLabel(activityInfo, userId));
+ private void updateFingerprintIcon(int newState) {
+ Drawable icon = getAnimationResForTransition(mLastState, newState);
+
+ if (icon == null) {
+ Log.e(TAG, "Animation not found");
+ return;
+ }
+
+ if (newState == STATE_FINGERPRINT) {
+ icon.setColorFilter(mFingerprintColor, PorterDuff.Mode.SRC_IN);
+ }
+
+ final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
+ ? (AnimatedVectorDrawable) icon
+ : null;
+
+ final ImageView fingerprint_icon = mLayout.findViewById(R.id.fingerprint_icon);
+ fingerprint_icon.setImageDrawable(icon);
+
+ if (animation != null) {
+ animation.forceAnimationOnUI();
+ animation.start();
+ }
+
+ mLastState = newState;
+ }
+
+ private Drawable getAnimationResForTransition(int oldState, int newState) {
+ int iconRes;
+ if (oldState == STATE_NONE && newState == STATE_FINGERPRINT) {
+ iconRes = R.drawable.lockscreen_fingerprint_draw_on_animation;
+ } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
+ iconRes = R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
+ } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
+ iconRes = R.drawable.lockscreen_fingerprint_error_state_to_fp_animation;
+ } else if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_AUTHENTICATED) {
+ iconRes = R.drawable.lockscreen_fingerprint_draw_off_animation;
+ } else {
+ return null;
+ }
+ return mContext.getDrawable(iconRes);
}
public WindowManager.LayoutParams getLayoutParams() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 89cc509..26fac6c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -211,11 +211,13 @@
}
/**
- * @return True unless setprop has been set to false, or we're in demo mode.
+ * @return True unless setprop has been set to false, we're in demo mode, or running tests in
+ * automation.
*/
private boolean shouldShow() {
return SystemProperties.getBoolean("persist.quickstep.onboarding.enabled",
- !(mContext.getSystemService(UserManager.class)).isDemoUser());
+ !(mContext.getSystemService(UserManager.class)).isDemoUser() &&
+ !ActivityManager.isRunningInTestHarness());
}
public void hide(boolean animate) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index 4454ef9..57d78dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -88,7 +88,7 @@
@Override
public void onRecentsAnimationStarted() {
mRecentsAnimationStarted = true;
- mQuickScrubController.cancelQuickSwitch();
+ mQuickScrubController.setRecentsAnimationStarted(true /* started */);
}
};
@@ -163,6 +163,7 @@
mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix);
mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix);
mRecentsAnimationStarted = false;
+ mQuickScrubController.setRecentsAnimationStarted(false /* started */);
break;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
index 378858a..dc0ea1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java
@@ -75,6 +75,7 @@
private boolean mDraggingActive;
private boolean mQuickScrubActive;
private boolean mAllowQuickSwitch;
+ private boolean mRecentsAnimationStarted;
private float mDownOffset;
private float mTranslation;
private int mTouchDownX;
@@ -279,7 +280,7 @@
}
// Control the button movement
- if (!mDraggingActive && exceededTouchSlop) {
+ if (!mDraggingActive && exceededTouchSlop && !mRecentsAnimationStarted) {
boolean allowDrag = !mDragPositive
? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown;
if (allowDrag) {
@@ -417,6 +418,13 @@
mDraggingActive = false;
}
+ public void setRecentsAnimationStarted(boolean started) {
+ mRecentsAnimationStarted = started;
+ if (started) {
+ cancelQuickSwitch();
+ }
+ }
+
public void cancelQuickSwitch() {
mAllowQuickSwitch = false;
mHandler.removeCallbacks(mLongPressRunnable);
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 7cd007b..1d5e47a 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -4702,6 +4702,10 @@
@ShellCommandResult
@Override
public int onCommand(@Nullable String cmd) {
+ if ("refresh_debug_properties".equals(cmd)) {
+ return refreshDebugProperties();
+ }
+
// For existing "adb shell ime <command>".
if ("ime".equals(cmd)) {
final String imeCommand = getNextArg();
@@ -4720,8 +4724,6 @@
return mService.handleShellCommandSetInputMethod(this);
case "reset":
return mService.handleShellCommandResetInputMethod(this);
- case "refresh_debug_properties":
- return refreshDebugProperties();
default:
getOutPrintWriter().println("Unknown command: " + imeCommand);
return ShellCommandResult.FAILURE;
diff --git a/services/core/java/com/android/server/broadcastradio/OWNERS b/services/core/java/com/android/server/broadcastradio/OWNERS
new file mode 100644
index 0000000..ea4421e
--- /dev/null
+++ b/services/core/java/com/android/server/broadcastradio/OWNERS
@@ -0,0 +1,2 @@
+twasilczyk@google.com
+randolphs@google.com
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 05c7f19..52f5917 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -2261,7 +2261,12 @@
Slog.i(TAG, "Moving uid " + uid + " to bucketIndex " + bucketIndex);
}
synchronized (mLock) {
- mJobs.forEachJobForSourceUid(uid, job -> job.setStandbyBucket(bucketIndex));
+ mJobs.forEachJobForSourceUid(uid, job -> {
+ // double-check uid vs package name to disambiguate shared uids
+ if (packageName.equals(job.getSourcePackageName())) {
+ job.setStandbyBucket(bucketIndex);
+ }
+ });
onControllerStateChanged();
}
});
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index 23a66ba..5460756 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -570,12 +570,6 @@
throws RemoteException, ServiceSpecificException {
byte[] locallyEncryptedKey;
try {
- // TODO: Remove the extraneous logging here
- Log.d(TAG, constructLoggingMessage("sessionEntry.getKeyClaimant()",
- sessionEntry.getKeyClaimant()));
- Log.d(TAG, constructLoggingMessage("sessionEntry.getVaultParams()",
- sessionEntry.getVaultParams()));
- Log.d(TAG, constructLoggingMessage("encryptedClaimResponse", encryptedClaimResponse));
locallyEncryptedKey = KeySyncUtils.decryptRecoveryClaimResponse(
sessionEntry.getKeyClaimant(),
sessionEntry.getVaultParams(),
@@ -594,10 +588,6 @@
}
try {
- // TODO: Remove the extraneous logging here
- Log.d(TAG, constructLoggingMessage("sessionEntry.getLskfHash()",
- sessionEntry.getLskfHash()));
- Log.d(TAG, constructLoggingMessage("locallyEncryptedKey", locallyEncryptedKey));
return KeySyncUtils.decryptRecoveryKey(sessionEntry.getLskfHash(), locallyEncryptedKey);
} catch (InvalidKeyException e) {
Log.e(TAG, "Got InvalidKeyException during decrypting recovery key", e);
@@ -636,9 +626,6 @@
byte[] encryptedKeyMaterial = applicationKey.getEncryptedKeyMaterial();
try {
- // TODO: Remove the extraneous logging here
- Log.d(TAG, constructLoggingMessage("recoveryKey", recoveryKey));
- Log.d(TAG, constructLoggingMessage("encryptedKeyMaterial", encryptedKeyMaterial));
byte[] keyMaterial =
KeySyncUtils.decryptApplicationKey(recoveryKey, encryptedKeyMaterial);
keyMaterialByAlias.put(alias, keyMaterial);
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 4b80e98..32e15c9 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -152,7 +152,8 @@
*/
public class NetworkStatsService extends INetworkStatsService.Stub {
static final String TAG = "NetworkStats";
- static final boolean LOGV = false;
+ static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
+ static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
private static final int MSG_PERFORM_POLL = 1;
private static final int MSG_UPDATE_IFACES = 2;
@@ -641,14 +642,14 @@
if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
&& (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE_ALL)
&& mSettings.getAugmentEnabled()) {
- Slog.d(TAG, "Resolving plan for " + template);
+ if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
final long token = Binder.clearCallingIdentity();
try {
final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
for (int subId : sm.getActiveSubscriptionIdList()) {
if (template.matchesSubscriberId(tm.getSubscriberId(subId))) {
- Slog.d(TAG, "Found active matching subId " + subId);
+ if (LOGD) Slog.d(TAG, "Found active matching subId " + subId);
final List<SubscriptionPlan> plans = sm.getSubscriptionPlans(subId);
if (!plans.isEmpty()) {
plan = plans.get(0);
@@ -658,7 +659,7 @@
} finally {
Binder.restoreCallingIdentity(token);
}
- Slog.d(TAG, "Resolved to plan " + plan);
+ if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
}
return plan;
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 3d60ee4..a4f20b01 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -204,9 +204,20 @@
}
DisplayContent createDisplayContent(final Display display, DisplayWindowController controller) {
+ final int displayId = display.getDisplayId();
+
+ // In select scenarios, it is possible that a DisplayContent will be created on demand
+ // rather than waiting for the controller. In this case, associate the controller and return
+ // the existing display.
+ final DisplayContent existing = getDisplayContent(displayId);
+
+ if (existing != null) {
+ existing.setController(controller);
+ return existing;
+ }
+
final DisplayContent dc =
new DisplayContent(display, mService, mWallpaperController, controller);
- final int displayId = display.getDisplayId();
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ace0944..26ac79e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1131,7 +1131,18 @@
throw new IllegalStateException("Display has not been initialialized");
}
- final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+
+ // Adding a window is an exception where the WindowManagerService can create the
+ // display instead of waiting for the ActivityManagerService to drive creation.
+ if (displayContent == null) {
+ final Display display = mDisplayManager.getDisplay(displayId);
+
+ if (display != null) {
+ displayContent = mRoot.createDisplayContent(display, null /* controller */);
+ }
+ }
+
if (displayContent == null) {
Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: "
+ displayId + ". Aborting.");
diff --git a/services/core/jni/BroadcastRadio/OWNERS b/services/core/jni/BroadcastRadio/OWNERS
new file mode 100644
index 0000000..ea4421e
--- /dev/null
+++ b/services/core/jni/BroadcastRadio/OWNERS
@@ -0,0 +1,2 @@
+twasilczyk@google.com
+randolphs@google.com
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/PersistentKeyChainSnapshotTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/PersistentKeyChainSnapshotTest.java
index 353a68f..17a4d34 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/PersistentKeyChainSnapshotTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/PersistentKeyChainSnapshotTest.java
@@ -176,7 +176,6 @@
() -> reader.readProtectionParams());
}
- @Ignore("Investigate why this is broken. b/73609806")
@Test
public void testKeyChainSnapshot() throws Exception {
PersistentKeyChainSnapshot writer = new PersistentKeyChainSnapshot();
@@ -201,7 +200,7 @@
KeyChainSnapshot snapshot = new KeyChainSnapshot.Builder()
.setSnapshotVersion(SNAPSHOT_VERSION)
.setKeyChainProtectionParams(protectionParamsList)
- .setEncryptedRecoveryKeyBlob(KEY_MATERIAL)
+ .setEncryptedRecoveryKeyBlob(RECOVERY_KEY_MATERIAL)
.setWrappedApplicationKeys(appKeysList)
.setMaxAttempts(MAX_ATTEMPTS)
.setCounterId(COUNTER_ID)
@@ -218,13 +217,11 @@
KeyChainSnapshot copy = reader.readKeyChainSnapshot();
assertThat(copy.getSnapshotVersion()).isEqualTo(SNAPSHOT_VERSION);
- assertThat(copy.getKeyChainProtectionParams()).hasSize(2);
+ assertThat(copy.getKeyChainProtectionParams()).hasSize(1);
assertThat(copy.getKeyChainProtectionParams().get(0).getUserSecretType()).isEqualTo(1);
- assertThat(copy.getKeyChainProtectionParams().get(1).getUserSecretType()).isEqualTo(2);
assertThat(copy.getEncryptedRecoveryKeyBlob()).isEqualTo(RECOVERY_KEY_MATERIAL);
- assertThat(copy.getWrappedApplicationKeys()).hasSize(2);
+ assertThat(copy.getWrappedApplicationKeys()).hasSize(1);
assertThat(copy.getWrappedApplicationKeys().get(0).getAlias()).isEqualTo(ALIAS);
- assertThat(copy.getWrappedApplicationKeys().get(1).getAlias()).isEqualTo(ALIAS2);
assertThat(copy.getMaxAttempts()).isEqualTo(MAX_ATTEMPTS);
assertThat(copy.getCounterId()).isEqualTo(COUNTER_ID);
assertThat(copy.getServerParams()).isEqualTo(SERVER_PARAMS);
@@ -237,7 +234,6 @@
verifyDeserialize(snapshot);
}
- @Ignore("Investigate why this is broken. b/73609806")
@Test
public void testKeyChainSnapshot_withManyKeysAndProtectionParams() throws Exception {
PersistentKeyChainSnapshot writer = new PersistentKeyChainSnapshot();
@@ -272,7 +268,7 @@
KeyChainSnapshot snapshot = new KeyChainSnapshot.Builder()
.setSnapshotVersion(SNAPSHOT_VERSION)
.setKeyChainProtectionParams(protectionParamsList)
- .setEncryptedRecoveryKeyBlob(KEY_MATERIAL)
+ .setEncryptedRecoveryKeyBlob(RECOVERY_KEY_MATERIAL)
.setWrappedApplicationKeys(appKeysList)
.setMaxAttempts(MAX_ATTEMPTS)
.setCounterId(COUNTER_ID)