Merge "Ensure keyguard is considered unlocked on devices that disable it."
diff --git a/api/current.txt b/api/current.txt
index d415f52..4fb9e0a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21946,6 +21946,7 @@
field public static final int ENCODING_DTS = 7; // 0x7
field public static final int ENCODING_DTS_HD = 8; // 0x8
field public static final int ENCODING_E_AC3 = 6; // 0x6
+ field public static final int ENCODING_E_AC3_JOC = 18; // 0x12
field public static final int ENCODING_IEC61937 = 13; // 0xd
field public static final int ENCODING_INVALID = 0; // 0x0
field public static final int ENCODING_MP3 = 9; // 0x9
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index f75678b..6e0bd3a 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -26,6 +26,7 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
+import android.os.FileUtils;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
@@ -34,6 +35,7 @@
import libcore.io.Streams;
+import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -583,7 +585,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
try (ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null, null)) {
- Streams.copy(new FileInputStream(fd.getFileDescriptor()), System.out);
+ FileUtils.copy(fd.getFileDescriptor(), FileDescriptor.out);
}
}
}
@@ -596,7 +598,7 @@
@Override
public void onExecute(IContentProvider provider) throws Exception {
try (ParcelFileDescriptor fd = provider.openFile(null, mUri, "w", null, null)) {
- Streams.copy(System.in, new FileOutputStream(fd.getFileDescriptor()));
+ FileUtils.copy(FileDescriptor.in, fd.getFileDescriptor());
}
}
}
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 76dbd6a..8101b16 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -38,6 +38,7 @@
src/external/StatsPuller.cpp \
src/external/StatsCompanionServicePuller.cpp \
src/external/SubsystemSleepStatePuller.cpp \
+ src/external/ResourceHealthManagerPuller.cpp \
src/external/CpuTimePerUidPuller.cpp \
src/external/CpuTimePerUidFreqPuller.cpp \
src/external/StatsPullerManagerImpl.cpp \
@@ -75,7 +76,8 @@
$(LOCAL_PATH)/../../core/java
statsd_common_static_libraries := \
- libplatformprotos
+ libhealthhalutils \
+ libplatformprotos \
statsd_common_shared_libraries := \
libbase \
@@ -93,6 +95,7 @@
libhidlbase \
libhidltransport \
libhwbinder \
+ android.hardware.health@2.0 \
android.hardware.power@1.0 \
android.hardware.power@1.1 \
libmemunreachable
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 4e570a6..b156d8d 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -99,7 +99,7 @@
}
// Pulled events will start at field 10000.
- // Next: 10019
+ // Next: 10021
oneof pulled {
WifiBytesTransfer wifi_bytes_transfer = 10000;
WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -120,6 +120,8 @@
CpuActiveTime cpu_active_time = 10016;
CpuClusterTime cpu_cluster_time = 10017;
DiskSpace disk_space = 10018;
+ RemainingBatteryCapacity remaining_battery_capacity = 10019;
+ FullBatteryCapacity full_battery_capacity = 10020;
}
}
@@ -757,8 +759,8 @@
// The tag used with the is_default for resetting sets of settings. This is generally null.
optional string tag = 5;
- // 1 indicates that this setting with tag should be resettable.
- optional int32 is_default = 6;
+ // True if this setting with tag should be resettable.
+ optional bool is_default = 6;
// The user ID associated. Defined in android/os/UserHandle.java
optional int32 user = 7;
@@ -1105,9 +1107,12 @@
optional int32 isolated_uid = 2;
- // 1 denotes we're creating an isolated uid and 0 denotes removal. We expect an isolated uid to
- // be removed before if it's used for another parent uid.
- optional int32 is_create = 3;
+ // We expect an isolated uid to be removed before if it's used for another parent uid.
+ enum Event {
+ REMOVED = 0;
+ CREATED = 1;
+ }
+ optional Event event = 3;
}
/**
@@ -1410,3 +1415,19 @@
// available bytes in download cache or temp directories
optional uint64 temp_available_bytes = 3;
}
+
+/**
+ * Pulls battery coulomb counter, which is the remaining battery charge in uAh.
+ * Logged from: frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+ */
+message RemainingBatteryCapacity {
+ optional int32 charge_uAh = 1;
+}
+
+/**
+ * Pulls battery capacity, which is the battery capacity when full in uAh.
+ * Logged from: frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+ */
+message FullBatteryCapacity {
+ optional int32 capacity_uAh = 1;
+}
diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
new file mode 100644
index 0000000..72fb5ff
--- /dev/null
+++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#define DEBUG true // STOPSHIP if true
+#include "Log.h"
+
+#include <android/hardware/health/2.0/IHealth.h>
+#include <healthhalutils/HealthHalUtils.h>
+#include "external/ResourceHealthManagerPuller.h"
+#include "external/StatsPuller.h"
+
+#include "ResourceHealthManagerPuller.h"
+#include "logd/LogEvent.h"
+#include "statslog.h"
+
+using android::hardware::hidl_vec;
+using android::hardware::health::V2_0::get_health_service;
+using android::hardware::health::V2_0::HealthInfo;
+using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_0::Result;
+using android::hardware::Return;
+using android::hardware::Void;
+
+using std::make_shared;
+using std::shared_ptr;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+sp<android::hardware::health::V2_0::IHealth> gHealthHal = nullptr;
+
+bool getHealthHal() {
+ if (gHealthHal == nullptr) {
+ gHealthHal = get_health_service();
+
+ }
+ return gHealthHal != nullptr;
+}
+
+ResourceHealthManagerPuller::ResourceHealthManagerPuller(int tagId) : StatsPuller(tagId) {
+}
+
+// TODO: add other health atoms (eg. Temperature).
+bool ResourceHealthManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
+ if (!getHealthHal()) {
+ ALOGE("Health Hal not loaded");
+ return false;
+ }
+
+ uint64_t timestamp = time(nullptr) * NS_PER_SEC;
+
+ data->clear();
+ bool result_success = true;
+
+ Return<void> ret = gHealthHal->getHealthInfo([&](Result r, HealthInfo v) {
+ if (r != Result::SUCCESS) {
+ result_success = false;
+ return;
+ }
+ if (mTagId == android::util::REMAINING_BATTERY_CAPACITY) {
+ auto ptr = make_shared<LogEvent>(android::util::REMAINING_BATTERY_CAPACITY, timestamp);
+ ptr->write(v.legacy.batteryChargeCounter);
+ ptr->init();
+ data->push_back(ptr);
+ } else if (mTagId == android::util::FULL_BATTERY_CAPACITY) {
+ auto ptr = make_shared<LogEvent>(android::util::FULL_BATTERY_CAPACITY, timestamp);
+ ptr->write(v.legacy.batteryFullCharge);
+ ptr->init();
+ data->push_back(ptr);
+ } else {
+ ALOGE("Unsupported tag in ResourceHealthManagerPuller: %d", mTagId);
+ }
+ });
+ if (!result_success || !ret.isOk()) {
+ ALOGE("getHealthHal() failed: health HAL service not available. Description: %s",
+ ret.description().c_str());
+ if (!ret.isOk() && ret.isDeadObject()) {
+ gHealthHal = nullptr;
+ }
+ return false;
+ }
+ return true;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.h b/cmds/statsd/src/external/ResourceHealthManagerPuller.h
new file mode 100644
index 0000000..9b238ea
--- /dev/null
+++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <utils/String16.h>
+#include "StatsPuller.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * Reads Ihealth.hal
+ */
+class ResourceHealthManagerPuller : public StatsPuller {
+public:
+ ResourceHealthManagerPuller(int tagId);
+ bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
+};
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
index 148c9ae..d8e8a41 100644
--- a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
@@ -23,10 +23,11 @@
#include <climits>
#include "CpuTimePerUidFreqPuller.h"
#include "CpuTimePerUidPuller.h"
-#include "SubsystemSleepStatePuller.h"
+#include "ResourceHealthManagerPuller.h"
#include "StatsCompanionServicePuller.h"
#include "StatsPullerManagerImpl.h"
#include "StatsService.h"
+#include "SubsystemSleepStatePuller.h"
#include "logd/LogEvent.h"
#include "statslog.h"
@@ -83,7 +84,10 @@
make_shared<StatsCompanionServicePuller>(android::util::WIFI_ACTIVITY_ENERGY_INFO)});
mPullers.insert({android::util::MODEM_ACTIVITY_INFO,
make_shared<StatsCompanionServicePuller>(android::util::MODEM_ACTIVITY_INFO)});
-
+ mPullers.insert({android::util::REMAINING_BATTERY_CAPACITY,
+ make_shared<ResourceHealthManagerPuller>(android::util::REMAINING_BATTERY_CAPACITY)});
+ mPullers.insert({android::util::FULL_BATTERY_CAPACITY,
+ make_shared<ResourceHealthManagerPuller>(android::util::FULL_BATTERY_CAPACITY)});
mStatsCompanionService = StatsService::getStatsCompanionService();
}
diff --git a/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java b/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java
index d39aa1d..57575ae 100644
--- a/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java
+++ b/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java
@@ -116,28 +116,32 @@
findViewById(R.id.plug).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED, 1);
+ StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED,
+ StatsLog.PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_AC);
}
});
findViewById(R.id.unplug).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED, 0);
+ StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED,
+ StatsLog.PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_NONE);
}
});
findViewById(R.id.screen_on).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, 2);
+ StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
+ StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_ON);
}
});
findViewById(R.id.screen_off).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, 1);
+ StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
+ StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF);
}
});
@@ -255,7 +259,9 @@
}
int[] uids = new int[] {mUids[id]};
String[] tags = new String[] {"acquire"};
- StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags, 0, name, 1);
+ StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags,
+ StatsLog.WAKELOCK_STATE_CHANGED__LEVEL__PARTIAL_WAKE_LOCK, name,
+ StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE);
StringBuilder sb = new StringBuilder();
sb.append("StagsLog.write(10, ").append(mUids[id]).append(", ").append(0)
.append(", ").append(name).append(", 1);");
@@ -269,7 +275,9 @@
}
int[] uids = new int[] {mUids[id]};
String[] tags = new String[] {"release"};
- StatsLog.write(10, uids, tags, 0, name, 0);
+ StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags,
+ StatsLog.WAKELOCK_STATE_CHANGED__LEVEL__PARTIAL_WAKE_LOCK, name,
+ StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE);
StringBuilder sb = new StringBuilder();
sb.append("StagsLog.write(10, ").append(mUids[id]).append(", ").append(0)
.append(", ").append(name).append(", 0);");
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 7c53ec1..21d245d 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -16,6 +16,11 @@
package android.os;
+import static android.system.OsConstants.SPLICE_F_MORE;
+import static android.system.OsConstants.SPLICE_F_MOVE;
+import static android.system.OsConstants.S_ISFIFO;
+import static android.system.OsConstants.S_ISREG;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.provider.DocumentsContract.Document;
@@ -29,6 +34,7 @@
import com.android.internal.annotations.VisibleForTesting;
+import libcore.io.IoUtils;
import libcore.util.EmptyArray;
import java.io.BufferedInputStream;
@@ -41,10 +47,12 @@
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
@@ -81,6 +89,14 @@
private static final File[] EMPTY = new File[0];
+ private static final boolean ENABLE_COPY_OPTIMIZATIONS = true;
+
+ private static final long COPY_CHECKPOINT_BYTES = 524288;
+
+ public interface CopyListener {
+ public void onProgress(long progress);
+ }
+
/**
* Set owner and mode of of given {@link File}.
*
@@ -185,6 +201,9 @@
return false;
}
+ /**
+ * @deprecated use {@link #copy(InputStream, OutputStream)} instead.
+ */
@Deprecated
public static boolean copyFile(File srcFile, File destFile) {
try {
@@ -195,14 +214,19 @@
}
}
- // copy a file from srcFile to destFile, return true if succeed, return
- // false if fail
+ /**
+ * @deprecated use {@link #copy(InputStream, OutputStream)} instead.
+ */
+ @Deprecated
public static void copyFileOrThrow(File srcFile, File destFile) throws IOException {
try (InputStream in = new FileInputStream(srcFile)) {
copyToFileOrThrow(in, destFile);
}
}
+ /**
+ * @deprecated use {@link #copy(InputStream, OutputStream)} instead.
+ */
@Deprecated
public static boolean copyToFile(InputStream inputStream, File destFile) {
try {
@@ -214,28 +238,153 @@
}
/**
- * Copy data from a source stream to destFile.
- * Return true if succeed, return false if failed.
+ * @deprecated use {@link #copy(InputStream, OutputStream)} instead.
*/
- public static void copyToFileOrThrow(InputStream inputStream, File destFile)
- throws IOException {
+ @Deprecated
+ public static void copyToFileOrThrow(InputStream in, File destFile) throws IOException {
if (destFile.exists()) {
destFile.delete();
}
- FileOutputStream out = new FileOutputStream(destFile);
- try {
- byte[] buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) >= 0) {
- out.write(buffer, 0, bytesRead);
- }
- } finally {
- out.flush();
+ try (FileOutputStream out = new FileOutputStream(destFile)) {
+ copy(in, out);
try {
- out.getFD().sync();
- } catch (IOException e) {
+ Os.fsync(out.getFD());
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
}
- out.close();
+ }
+ }
+
+ public static void copy(File from, File to) throws IOException {
+ try (FileInputStream in = new FileInputStream(from);
+ FileOutputStream out = new FileOutputStream(to)) {
+ copy(in, out);
+ }
+ }
+
+ public static void copy(InputStream in, OutputStream out) throws IOException {
+ copy(in, out, null, null);
+ }
+
+ public static void copy(InputStream in, OutputStream out, CopyListener listener,
+ CancellationSignal signal) throws IOException {
+ if (ENABLE_COPY_OPTIMIZATIONS) {
+ if (in instanceof FileInputStream && out instanceof FileOutputStream) {
+ copy(((FileInputStream) in).getFD(), ((FileOutputStream) out).getFD(),
+ listener, signal);
+ }
+ }
+
+ // Worse case fallback to userspace
+ copyInternalUserspace(in, out, listener, signal);
+ }
+
+ public static void copy(FileDescriptor in, FileDescriptor out) throws IOException {
+ copy(in, out, null, null);
+ }
+
+ public static void copy(FileDescriptor in, FileDescriptor out, CopyListener listener,
+ CancellationSignal signal) throws IOException {
+ if (ENABLE_COPY_OPTIMIZATIONS) {
+ try {
+ final StructStat st_in = Os.fstat(in);
+ final StructStat st_out = Os.fstat(out);
+ if (S_ISREG(st_in.st_mode) && S_ISREG(st_out.st_mode)) {
+ copyInternalSendfile(in, out, listener, signal);
+ } else if (S_ISFIFO(st_in.st_mode) || S_ISFIFO(st_out.st_mode)) {
+ copyInternalSplice(in, out, listener, signal);
+ }
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
+ }
+ }
+
+ // Worse case fallback to userspace
+ copyInternalUserspace(in, out, listener, signal);
+ }
+
+ /**
+ * Requires one of input or output to be a pipe.
+ */
+ @VisibleForTesting
+ public static void copyInternalSplice(FileDescriptor in, FileDescriptor out,
+ CopyListener listener, CancellationSignal signal) throws ErrnoException {
+ long progress = 0;
+ long checkpoint = 0;
+
+ long t;
+ while ((t = Os.splice(in, null, out, null, COPY_CHECKPOINT_BYTES,
+ SPLICE_F_MOVE | SPLICE_F_MORE)) != 0) {
+ progress += t;
+ checkpoint += t;
+
+ if (checkpoint >= COPY_CHECKPOINT_BYTES) {
+ if (signal != null) {
+ signal.throwIfCanceled();
+ }
+ if (listener != null) {
+ listener.onProgress(progress);
+ }
+ checkpoint = 0;
+ }
+ }
+ }
+
+ /**
+ * Requires both input and output to be a regular file.
+ */
+ @VisibleForTesting
+ public static void copyInternalSendfile(FileDescriptor in, FileDescriptor out,
+ CopyListener listener, CancellationSignal signal) throws ErrnoException {
+ long progress = 0;
+ long checkpoint = 0;
+
+ long t;
+ while ((t = Os.sendfile(out, in, null, COPY_CHECKPOINT_BYTES)) != 0) {
+ progress += t;
+ checkpoint += t;
+
+ if (checkpoint >= COPY_CHECKPOINT_BYTES) {
+ if (signal != null) {
+ signal.throwIfCanceled();
+ }
+ if (listener != null) {
+ listener.onProgress(progress);
+ }
+ checkpoint = 0;
+ }
+ }
+ }
+
+ @VisibleForTesting
+ public static void copyInternalUserspace(FileDescriptor in, FileDescriptor out,
+ CopyListener listener, CancellationSignal signal) throws IOException {
+ copyInternalUserspace(new FileInputStream(in), new FileOutputStream(out), listener, signal);
+ }
+
+ @VisibleForTesting
+ public static void copyInternalUserspace(InputStream in, OutputStream out,
+ CopyListener listener, CancellationSignal signal) throws IOException {
+ long progress = 0;
+ long checkpoint = 0;
+ byte[] buffer = new byte[8192];
+
+ int t;
+ while ((t = in.read(buffer)) != -1) {
+ out.write(buffer, 0, t);
+
+ progress += t;
+ checkpoint += t;
+
+ if (checkpoint >= COPY_CHECKPOINT_BYTES) {
+ if (signal != null) {
+ signal.throwIfCanceled();
+ }
+ if (listener != null) {
+ listener.onProgress(progress);
+ }
+ checkpoint = 0;
+ }
}
}
@@ -797,4 +946,69 @@
}
return val * pow;
}
+
+ @VisibleForTesting
+ public static class MemoryPipe extends Thread implements AutoCloseable {
+ private final FileDescriptor[] pipe;
+ private final byte[] data;
+ private final boolean sink;
+
+ private MemoryPipe(byte[] data, boolean sink) throws IOException {
+ try {
+ this.pipe = Os.pipe();
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
+ }
+ this.data = data;
+ this.sink = sink;
+ }
+
+ private MemoryPipe startInternal() {
+ super.start();
+ return this;
+ }
+
+ public static MemoryPipe createSource(byte[] data) throws IOException {
+ return new MemoryPipe(data, false).startInternal();
+ }
+
+ public static MemoryPipe createSink(byte[] data) throws IOException {
+ return new MemoryPipe(data, true).startInternal();
+ }
+
+ public FileDescriptor getFD() {
+ return sink ? pipe[1] : pipe[0];
+ }
+
+ public FileDescriptor getInternalFD() {
+ return sink ? pipe[0] : pipe[1];
+ }
+
+ @Override
+ public void run() {
+ final FileDescriptor fd = getInternalFD();
+ try {
+ int i = 0;
+ while (i < data.length) {
+ if (sink) {
+ i += Os.read(fd, data, i, data.length - i);
+ } else {
+ i += Os.write(fd, data, i, data.length - i);
+ }
+ }
+ } catch (IOException | ErrnoException e) {
+ throw new RuntimeException(e);
+ } finally {
+ if (sink) {
+ SystemClock.sleep(TimeUnit.SECONDS.toMillis(1));
+ }
+ IoUtils.closeQuietly(fd);
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ IoUtils.closeQuietly(getFD());
+ }
+ }
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1f0d683..ad0ce49 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1903,7 +1903,7 @@
cp.call(cr.getPackageName(), mCallSetCommand, name, arg);
String newValue = getStringForUser(cr, name, userHandle);
StatsLog.write(StatsLog.SETTING_CHANGED, name, value, newValue, prevValue, tag,
- makeDefault ? 1 : 0, userHandle);
+ makeDefault, userHandle);
} catch (RemoteException e) {
Log.w(TAG, "Can't set key " + name + " in " + mUri, e);
return false;
diff --git a/core/java/android/service/settings/suggestions/Suggestion.java b/core/java/android/service/settings/suggestions/Suggestion.java
index 11e1e67..e97f963a 100644
--- a/core/java/android/service/settings/suggestions/Suggestion.java
+++ b/core/java/android/service/settings/suggestions/Suggestion.java
@@ -40,6 +40,7 @@
*/
@IntDef(flag = true, prefix = { "FLAG_" }, value = {
FLAG_HAS_BUTTON,
+ FLAG_ICON_TINTABLE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Flags {
@@ -49,6 +50,10 @@
* Flag for suggestion type with a single button
*/
public static final int FLAG_HAS_BUTTON = 1 << 0;
+ /**
+ * @hide
+ */
+ public static final int FLAG_ICON_TINTABLE = 1 << 1;
private final String mId;
private final CharSequence mTitle;
diff --git a/core/java/android/widget/MediaControlView2.java b/core/java/android/widget/MediaControlView2.java
index 2e4cccf..5f6d9ce 100644
--- a/core/java/android/widget/MediaControlView2.java
+++ b/core/java/android/widget/MediaControlView2.java
@@ -19,7 +19,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.content.Context;
import android.media.session.MediaController;
import android.media.update.ApiLoader;
@@ -163,14 +162,6 @@
}
/**
- * @hide
- */
- @SystemApi
- public MediaControlView2Provider getProvider() {
- return mProvider;
- }
-
- /**
* Sets MediaController instance to control corresponding MediaSession.
*/
public void setController(MediaController controller) {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 7def876..40dcf25b 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3880,7 +3880,8 @@
public void addIsolatedUidLocked(int isolatedUid, int appUid) {
mIsolatedUids.put(isolatedUid, appUid);
- StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, appUid, isolatedUid, 1);
+ StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, appUid, isolatedUid,
+ StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
final Uid u = getUidStatsLocked(appUid);
u.addIsolatedUid(isolatedUid);
}
@@ -3904,7 +3905,8 @@
*/
public void removeIsolatedUidLocked(int isolatedUid) {
StatsLog.write(
- StatsLog.ISOLATED_UID_CHANGED, mIsolatedUids.get(isolatedUid, -1), isolatedUid, 0);
+ StatsLog.ISOLATED_UID_CHANGED, mIsolatedUids.get(isolatedUid, -1),
+ isolatedUid, StatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED);
final int idx = mIsolatedUids.indexOfKey(isolatedUid);
if (idx >= 0) {
final int ownerUid = mIsolatedUids.valueAt(idx);
@@ -4255,10 +4257,12 @@
if (wc != null) {
StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(),
- getPowerManagerWakeLockLevel(type), name, 1);
+ getPowerManagerWakeLockLevel(type), name,
+ StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE);
} else {
StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null,
- getPowerManagerWakeLockLevel(type), name, 1);
+ getPowerManagerWakeLockLevel(type), name,
+ StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE);
}
}
}
@@ -4298,10 +4302,12 @@
getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
if (wc != null) {
StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, wc.getUids(), wc.getTags(),
- getPowerManagerWakeLockLevel(type), name, 0);
+ getPowerManagerWakeLockLevel(type), name,
+ StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE);
} else {
StatsLog.write_non_chained(StatsLog.WAKELOCK_STATE_CHANGED, uid, null,
- getPowerManagerWakeLockLevel(type), name, 0);
+ getPowerManagerWakeLockLevel(type), name,
+ StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE);
}
}
}
@@ -4426,7 +4432,8 @@
public void noteLongPartialWakelockStart(String name, String historyName, int uid) {
StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
- uid, null, name, historyName, 1);
+ uid, null, name, historyName,
+ StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
uid = mapUid(uid);
noteLongPartialWakeLockStartInternal(name, historyName, uid);
@@ -4439,7 +4446,8 @@
final int uid = mapUid(workSource.get(i));
noteLongPartialWakeLockStartInternal(name, historyName, uid);
StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
- workSource.get(i), workSource.getName(i), name, historyName, 1);
+ workSource.get(i), workSource.getName(i), name, historyName,
+ StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
}
final ArrayList<WorkChain> workChains = workSource.getWorkChains();
@@ -4450,7 +4458,8 @@
noteLongPartialWakeLockStartInternal(name, historyName, uid);
StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), name, historyName, 1);
+ workChain.getUids(), workChain.getTags(), name, historyName,
+ StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__ON);
}
}
}
@@ -4470,8 +4479,8 @@
}
public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
- StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
- uid, null, name, historyName, 0);
+ StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, uid, null,
+ name, historyName, StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
uid = mapUid(uid);
noteLongPartialWakeLockFinishInternal(name, historyName, uid);
@@ -4484,7 +4493,8 @@
final int uid = mapUid(workSource.get(i));
noteLongPartialWakeLockFinishInternal(name, historyName, uid);
StatsLog.write_non_chained(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
- workSource.get(i), workSource.getName(i), name, historyName, 0);
+ workSource.get(i), workSource.getName(i), name, historyName,
+ StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
}
final ArrayList<WorkChain> workChains = workSource.getWorkChains();
@@ -4494,7 +4504,8 @@
final int uid = workChain.getAttributionUid();
noteLongPartialWakeLockFinishInternal(name, historyName, uid);
StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), name, historyName, 0);
+ workChain.getUids(), workChain.getTags(), name, historyName,
+ StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED__STATE__OFF);
}
}
}
@@ -4518,7 +4529,8 @@
long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
timer.add(deltaUptime * 1000, 1); // time in in microseconds
- StatsLog.write(StatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, deltaUptime * 1000);
+ StatsLog.write(StatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason,
+ /* duration_usec */ deltaUptime * 1000);
mLastWakeupReason = null;
}
}
@@ -4659,10 +4671,12 @@
mGpsNesting++;
if (workChain == null) {
- StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 1);
+ StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null,
+ StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON);
} else {
StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), 1);
+ workChain.getUids(), workChain.getTags(),
+ StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON);
}
getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
@@ -4683,10 +4697,11 @@
}
if (workChain == null) {
- StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null, 0);
+ StatsLog.write_non_chained(StatsLog.GPS_SCAN_STATE_CHANGED, uid, null,
+ StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF);
} else {
StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, workChain.getUids(),
- workChain.getTags(), 0);
+ workChain.getTags(), StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF);
}
getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
@@ -4941,7 +4956,9 @@
mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
}
addHistoryRecordLocked(elapsedRealtime, uptime);
- StatsLog.write(StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, enabled ? 1 : 0);
+ StatsLog.write(StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, enabled ?
+ StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__ON :
+ StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED__STATE__OFF);
}
}
@@ -5545,16 +5562,19 @@
if (workChain != null) {
StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), 1);
+ workChain.getUids(), workChain.getTags(),
+ StatsLog.BLE_SCAN_STATE_CHANGED__STATE__ON);
if (isUnoptimized) {
StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), 1);
+ workChain.getUids(), workChain.getTags(),
+ StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__ON);
}
} else {
- StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, uid, null, 1);
+ StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, uid, null,
+ StatsLog.BLE_SCAN_STATE_CHANGED__STATE__ON);
if (isUnoptimized) {
StatsLog.write_non_chained(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, uid, null,
- 1);
+ StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__ON);
}
}
@@ -5594,16 +5614,19 @@
if (workChain != null) {
StatsLog.write(
- StatsLog.BLE_SCAN_STATE_CHANGED, workChain.getUids(), workChain.getTags(), 0);
+ StatsLog.BLE_SCAN_STATE_CHANGED, workChain.getUids(), workChain.getTags(),
+ StatsLog.BLE_SCAN_STATE_CHANGED__STATE__OFF);
if (isUnoptimized) {
StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), 0);
+ workChain.getUids(), workChain.getTags(),
+ StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__OFF);
}
} else {
- StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, uid, null, 0);
+ StatsLog.write_non_chained(StatsLog.BLE_SCAN_STATE_CHANGED, uid, null,
+ StatsLog.BLE_SCAN_STATE_CHANGED__STATE__OFF);
if (isUnoptimized) {
StatsLog.write_non_chained(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, uid, null,
- 0);
+ StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__OFF);
}
}
@@ -5656,7 +5679,8 @@
for (int j = 0; j < allWorkChains.size(); ++j) {
StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED,
allWorkChains.get(j).getUids(),
- allWorkChains.get(j).getTags(), 0);
+ allWorkChains.get(j).getTags(),
+ StatsLog.BLE_SCAN_STATE_CHANGED__STATE__OFF);
}
allWorkChains.clear();
}
@@ -5666,7 +5690,8 @@
for (int j = 0; j < unoptimizedWorkChains.size(); ++j) {
StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED,
unoptimizedWorkChains.get(j).getUids(),
- unoptimizedWorkChains.get(j).getTags(), 0);
+ unoptimizedWorkChains.get(j).getTags(),
+ StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED__STATE__OFF);
}
unoptimizedWorkChains.clear();
}
@@ -6011,7 +6036,8 @@
for (int i=0; i<N; i++) {
final int uid = mapUid(ws.get(i));
noteFullWifiLockAcquiredLocked(uid);
- StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i), 1);
+ StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i),
+ StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -6021,7 +6047,8 @@
final int uid = mapUid(workChain.getAttributionUid());
noteFullWifiLockAcquiredLocked(uid);
StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), 1);
+ workChain.getUids(), workChain.getTags(),
+ StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON);
}
}
}
@@ -6031,7 +6058,8 @@
for (int i=0; i<N; i++) {
final int uid = mapUid(ws.get(i));
noteFullWifiLockReleasedLocked(uid);
- StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i), 0);
+ StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, ws.get(i), ws.getName(i),
+ StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -6041,7 +6069,8 @@
final int uid = mapUid(workChain.getAttributionUid());
noteFullWifiLockReleasedLocked(uid);
StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), 0);
+ workChain.getUids(), workChain.getTags(),
+ StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF);
}
}
}
@@ -6052,7 +6081,7 @@
final int uid = mapUid(ws.get(i));
noteWifiScanStartedLocked(uid);
StatsLog.write_non_chained(StatsLog.WIFI_SCAN_STATE_CHANGED, ws.get(i), ws.getName(i),
- 1);
+ StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__ON);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -6062,7 +6091,7 @@
final int uid = mapUid(workChain.getAttributionUid());
noteWifiScanStartedLocked(uid);
StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED, workChain.getUids(),
- workChain.getTags(), 1);
+ workChain.getTags(), StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__ON);
}
}
}
@@ -6073,7 +6102,7 @@
final int uid = mapUid(ws.get(i));
noteWifiScanStoppedLocked(uid);
StatsLog.write_non_chained(StatsLog.WIFI_SCAN_STATE_CHANGED, ws.get(i), ws.getName(i),
- 0);
+ StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__OFF);
}
final List<WorkChain> workChains = ws.getWorkChains();
@@ -6083,7 +6112,8 @@
final int uid = mapUid(workChain.getAttributionUid());
noteWifiScanStoppedLocked(uid);
StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED,
- workChain.getUids(), workChain.getTags(), 0);
+ workChain.getUids(), workChain.getTags(),
+ StatsLog.WIFI_SCAN_STATE_CHANGED__STATE__OFF);
}
}
}
@@ -7035,7 +7065,8 @@
}
mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
StatsLog.write_non_chained(
- StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null, 1);
+ StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null,
+ StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__ON);
}
}
@@ -7045,7 +7076,8 @@
mWifiMulticastEnabled = false;
mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
StatsLog.write_non_chained(
- StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null, 0);
+ StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED, getUid(), null,
+ StatsLog.WIFI_MULTICAST_LOCK_STATE_CHANGED__STATE__OFF);
}
}
@@ -7098,14 +7130,16 @@
public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null, 1);
+ StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__ON);
}
public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
if (mAudioTurnedOnTimer != null) {
mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
if (!mAudioTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
- StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null, 0);
+ StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
}
}
}
@@ -7113,7 +7147,8 @@
public void noteResetAudioLocked(long elapsedRealtimeMs) {
if (mAudioTurnedOnTimer != null) {
mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null, 0);
+ StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
}
}
@@ -7127,7 +7162,8 @@
public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), null, 1);
+ StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), null,
+ StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__ON);
}
public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
@@ -7135,7 +7171,7 @@
mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
if (!mVideoTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(),
- null, 0);
+ null, StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__OFF);
}
}
}
@@ -7144,7 +7180,7 @@
if (mVideoTurnedOnTimer != null) {
mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), null,
- 0);
+ StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__OFF);
}
}
@@ -7158,7 +7194,8 @@
public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) {
createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,1);
+ StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
+ StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
}
public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) {
@@ -7166,7 +7203,7 @@
mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
if (!mFlashlightTurnedOnTimer.isRunningLocked()) {
StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
- 0);
+ StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
}
}
}
@@ -7174,7 +7211,8 @@
public void noteResetFlashlightLocked(long elapsedRealtimeMs) {
if (mFlashlightTurnedOnTimer != null) {
mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null, 0);
+ StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
+ StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
}
}
@@ -7188,14 +7226,16 @@
public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) {
createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null, 1);
+ StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
+ StatsLog.CAMERA_STATE_CHANGED__STATE__ON);
}
public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) {
if (mCameraTurnedOnTimer != null) {
mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
if (!mCameraTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
- StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null, 0);
+ StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
+ StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
}
}
}
@@ -7203,7 +7243,8 @@
public void noteResetCameraLocked(long elapsedRealtimeMs) {
if (mCameraTurnedOnTimer != null) {
mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null, 0);
+ StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
+ StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
}
}
@@ -9777,7 +9818,8 @@
DualTimer t = mSyncStats.startObject(name);
if (t != null) {
t.startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, getUid(), null, name, 1);
+ StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, getUid(), null, name,
+ StatsLog.SYNC_STATE_CHANGED__STATE__ON);
}
}
@@ -9786,7 +9828,8 @@
if (t != null) {
t.stopRunningLocked(elapsedRealtimeMs);
if (!t.isRunningLocked()) { // only tell statsd if truly stopped
- StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, getUid(), null, name, 0);
+ StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, getUid(), null, name,
+ StatsLog.SYNC_STATE_CHANGED__STATE__OFF);
}
}
}
@@ -9796,7 +9839,7 @@
if (t != null) {
t.startRunningLocked(elapsedRealtimeMs);
StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), null,
- name, 1);
+ name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED);
}
}
@@ -9806,7 +9849,7 @@
t.stopRunningLocked(elapsedRealtimeMs);
if (!t.isRunningLocked()) { // only tell statsd if truly stopped
StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), null,
- name, 0);
+ name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED);
}
}
if (mBsi.mOnBatteryTimeBase.isRunning()) {
@@ -9919,7 +9962,7 @@
t.startRunningLocked(elapsedRealtimeMs);
if (sensor != Sensor.GPS) {
StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, getUid(), null, sensor,
- 1);
+ StatsLog.SENSOR_STATE_CHANGED__STATE__ON);
}
}
@@ -9930,7 +9973,7 @@
t.stopRunningLocked(elapsedRealtimeMs);
if (sensor != Sensor.GPS) {
StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, getUid(), null,
- sensor, 0);
+ sensor, StatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
}
}
}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index f9a2341..e69a360 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -55,6 +55,8 @@
public static final int ONLY_USE_SYSTEM_OAT_FILES = 1 << 10;
/** Do not enfore hidden API access restrictions. */
public static final int DISABLE_HIDDEN_API_CHECKS = 1 << 11;
+ /** Force generation of native debugging information for backtraces. */
+ public static final int DEBUG_GENERATE_MINI_DEBUG_INFO = 1 << 12;
/** No external storage should be mounted. */
public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index f70d3c2..ebb5f9f 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -132,12 +132,6 @@
void clickQsTile(in ComponentName tile);
void handleSystemKey(in int key);
- /**
- * Methods to show toast messages for screen pinning
- */
- void showPinningEnterExitToast(boolean entering);
- void showPinningEscapeToast();
-
void showShutdownUi(boolean isReboot, String reason);
// Used to show the dialog when FingerprintService starts authentication
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index adf4287..cb0b53c 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -81,12 +81,6 @@
void clickTile(in ComponentName tile);
void handleSystemKey(in int key);
- /**
- * Methods to show toast messages for screen pinning
- */
- void showPinningEnterExitToast(boolean entering);
- void showPinningEscapeToast();
-
// Used to show the dialog when FingerprintService starts authentication
void showFingerprintDialog(in Bundle bundle, IFingerprintDialogReceiver receiver);
// Used to hide the dialog when a finger is authenticated
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 71550be..f8885a2 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -160,7 +160,7 @@
final File file = new File(mBasePath, name);
final FileInputStream is = new FileInputStream(file);
try {
- Streams.copy(is, zos);
+ FileUtils.copy(is, zos);
} finally {
IoUtils.closeQuietly(is);
}
diff --git a/core/jni/android/graphics/AnimatedImageDrawable.cpp b/core/jni/android/graphics/AnimatedImageDrawable.cpp
index c88cf5c..ba56d59 100644
--- a/core/jni/android/graphics/AnimatedImageDrawable.cpp
+++ b/core/jni/android/graphics/AnimatedImageDrawable.cpp
@@ -26,10 +26,11 @@
#include <SkPictureRecorder.h>
#include <hwui/AnimatedImageDrawable.h>
#include <hwui/Canvas.h>
+#include <utils/Looper.h>
using namespace android;
-static jmethodID gAnimatedImageDrawable_postOnAnimationEndMethodID;
+static jmethodID gAnimatedImageDrawable_onAnimationEndMethodID;
// Note: jpostProcess holds a handle to the ImageDecoder.
static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
@@ -123,9 +124,9 @@
return drawable->start();
}
-static void AnimatedImageDrawable_nStop(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
+static jboolean AnimatedImageDrawable_nStop(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
- drawable->stop();
+ return drawable->stop();
}
// Java's LOOP_INFINITE relies on this being the same.
@@ -137,33 +138,63 @@
drawable->setRepetitionCount(loopCount);
}
-class JniAnimationEndListener : public OnAnimationEndListener {
+class InvokeListener : public MessageHandler {
public:
- JniAnimationEndListener(JNIEnv* env, jobject javaObject) {
+ InvokeListener(JNIEnv* env, jobject javaObject) {
LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJvm) != JNI_OK);
- mJavaObject = env->NewGlobalRef(javaObject);
+ // Hold a weak reference to break a cycle that would prevent GC.
+ mWeakRef = env->NewWeakGlobalRef(javaObject);
}
- ~JniAnimationEndListener() override {
+ ~InvokeListener() override {
auto* env = get_env_or_die(mJvm);
- env->DeleteGlobalRef(mJavaObject);
+ env->DeleteWeakGlobalRef(mWeakRef);
}
- void onAnimationEnd() override {
+ virtual void handleMessage(const Message&) override {
auto* env = get_env_or_die(mJvm);
- env->CallVoidMethod(mJavaObject, gAnimatedImageDrawable_postOnAnimationEndMethodID);
+ jobject localRef = env->NewLocalRef(mWeakRef);
+ if (localRef) {
+ env->CallVoidMethod(localRef, gAnimatedImageDrawable_onAnimationEndMethodID);
+ }
}
private:
JavaVM* mJvm;
- jobject mJavaObject;
+ jweak mWeakRef;
+};
+
+class JniAnimationEndListener : public OnAnimationEndListener {
+public:
+ JniAnimationEndListener(sp<Looper>&& looper, JNIEnv* env, jobject javaObject) {
+ mListener = new InvokeListener(env, javaObject);
+ mLooper = std::move(looper);
+ }
+
+ void onAnimationEnd() override { mLooper->sendMessage(mListener, 0); }
+
+private:
+ sp<InvokeListener> mListener;
+ sp<Looper> mLooper;
};
static void AnimatedImageDrawable_nSetOnAnimationEndListener(JNIEnv* env, jobject /*clazz*/,
jlong nativePtr, jobject jdrawable) {
auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
- drawable->setOnAnimationEndListener(std::unique_ptr<OnAnimationEndListener>(
- new JniAnimationEndListener(env, jdrawable)));
+ if (!jdrawable) {
+ drawable->setOnAnimationEndListener(nullptr);
+ } else {
+ sp<Looper> looper = Looper::getForThread();
+ if (!looper.get()) {
+ doThrowISE(env,
+ "Must set AnimatedImageDrawable's AnimationCallback on a thread with a "
+ "looper!");
+ return;
+ }
+
+ drawable->setOnAnimationEndListener(
+ std::make_unique<JniAnimationEndListener>(std::move(looper), env, jdrawable));
+ }
}
static long AnimatedImageDrawable_nNativeByteSize(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) {
@@ -186,7 +217,7 @@
{ "nSetColorFilter", "(JJ)V", (void*) AnimatedImageDrawable_nSetColorFilter },
{ "nIsRunning", "(J)Z", (void*) AnimatedImageDrawable_nIsRunning },
{ "nStart", "(J)Z", (void*) AnimatedImageDrawable_nStart },
- { "nStop", "(J)V", (void*) AnimatedImageDrawable_nStop },
+ { "nStop", "(J)Z", (void*) AnimatedImageDrawable_nStop },
{ "nSetLoopCount", "(JI)V", (void*) AnimatedImageDrawable_nSetLoopCount },
{ "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
{ "nNativeByteSize", "(J)J", (void*) AnimatedImageDrawable_nNativeByteSize },
@@ -195,7 +226,7 @@
int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) {
jclass animatedImageDrawable_class = FindClassOrDie(env, "android/graphics/drawable/AnimatedImageDrawable");
- gAnimatedImageDrawable_postOnAnimationEndMethodID = GetMethodIDOrDie(env, animatedImageDrawable_class, "postOnAnimationEnd", "()V");
+ gAnimatedImageDrawable_onAnimationEndMethodID = GetMethodIDOrDie(env, animatedImageDrawable_class, "onAnimationEnd", "()V");
return android::RegisterMethodsOrDie(env, "android/graphics/drawable/AnimatedImageDrawable",
gAnimatedImageDrawableMethods, NELEM(gAnimatedImageDrawableMethods));
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index dd3e6f0..937b3ff 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -44,11 +44,9 @@
struct NativeFamilyBuilder {
NativeFamilyBuilder(uint32_t langId, int variant)
- : langId(langId), variant(static_cast<minikin::FontFamily::Variant>(variant)),
- allowUnsupportedFont(false) {}
+ : langId(langId), variant(static_cast<minikin::FontFamily::Variant>(variant)) {}
uint32_t langId;
minikin::FontFamily::Variant variant;
- bool allowUnsupportedFont;
std::vector<minikin::Font> fonts;
std::vector<minikin::FontVariation> axes;
};
@@ -70,22 +68,17 @@
}
std::unique_ptr<NativeFamilyBuilder> builder(
reinterpret_cast<NativeFamilyBuilder*>(builderPtr));
+ if (builder->fonts.empty()) {
+ return 0;
+ }
std::shared_ptr<minikin::FontFamily> family = std::make_shared<minikin::FontFamily>(
builder->langId, builder->variant, std::move(builder->fonts));
- if (family->getCoverage().length() == 0 && !builder->allowUnsupportedFont) {
+ if (family->getCoverage().length() == 0) {
return 0;
}
return reinterpret_cast<jlong>(new FontFamilyWrapper(std::move(family)));
}
-static void FontFamily_allowUnsupportedFont(jlong builderPtr) {
- if (builderPtr == 0) {
- return;
- }
- NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
- builder->allowUnsupportedFont = true;
-}
-
static void FontFamily_abort(jlong builderPtr) {
NativeFamilyBuilder* builder = reinterpret_cast<NativeFamilyBuilder*>(builderPtr);
delete builder;
@@ -270,7 +263,6 @@
static const JNINativeMethod gFontFamilyMethods[] = {
{ "nInitBuilder", "(Ljava/lang/String;I)J", (void*)FontFamily_initBuilder },
{ "nCreateFamily", "(J)J", (void*)FontFamily_create },
- { "nAllowUnsupportedFont", "(J)V", (void*)FontFamily_allowUnsupportedFont },
{ "nAbort", "(J)V", (void*)FontFamily_abort },
{ "nUnrefFamily", "(J)V", (void*)FontFamily_unref },
{ "nAddFont", "(JLjava/nio/ByteBuffer;III)Z", (void*)FontFamily_addFont },
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index c79f5bd..12da273 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -36,6 +36,7 @@
#define ENCODING_AAC_ELD 15
#define ENCODING_AAC_XHE 16
#define ENCODING_AC4 17
+#define ENCODING_E_AC3_JOC 18
#define ENCODING_INVALID 0
#define ENCODING_DEFAULT 1
@@ -80,6 +81,8 @@
return AUDIO_FORMAT_AAC; // FIXME temporary value, needs addition of xHE-AAC
case ENCODING_AC4:
return AUDIO_FORMAT_AC4;
+ // case ENCODING_E_AC3_JOC: // FIXME Not defined on the native side yet
+ // return AUDIO_FORMAT_E_AC3_JOC;
case ENCODING_DEFAULT:
return AUDIO_FORMAT_DEFAULT;
default:
@@ -130,6 +133,8 @@
// return ENCODING_AAC_XHE;
case AUDIO_FORMAT_AC4:
return ENCODING_AC4;
+ // case AUDIO_FORMAT_E_AC3_JOC: // FIXME Not defined on the native side yet
+ // return ENCODING_E_AC3_JOC;
case AUDIO_FORMAT_DEFAULT:
return ENCODING_DEFAULT;
default:
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3b752c4..224503b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4423,6 +4423,15 @@
<!-- DO NOT TRANSLATE -->
<string name="date_picker_day_typeface">sans-serif-medium</string>
+ <!-- Notify use that they are in Lock-to-app -->
+ <string name="lock_to_app_toast">To unpin this screen, touch & hold Back and Overview
+ buttons</string>
+
+ <!-- Starting lock-to-app indication. -->
+ <string name="lock_to_app_start">Screen pinned</string>
+ <!-- Exting lock-to-app indication. -->
+ <string name="lock_to_app_exit">Screen unpinned</string>
+
<!-- Lock-to-app unlock pin string -->
<string name="lock_to_app_unlock_pin">Ask for PIN before unpinning</string>
<!-- Lock-to-app unlock pattern string -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fee5a80..a338f89 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -767,6 +767,9 @@
<java-symbol type="string" name="kilobyteShort" />
<java-symbol type="string" name="last_month" />
<java-symbol type="string" name="launchBrowserDefault" />
+ <java-symbol type="string" name="lock_to_app_toast" />
+ <java-symbol type="string" name="lock_to_app_start" />
+ <java-symbol type="string" name="lock_to_app_exit" />
<java-symbol type="string" name="lock_to_app_unlock_pin" />
<java-symbol type="string" name="lock_to_app_unlock_pattern" />
<java-symbol type="string" name="lock_to_app_unlock_password" />
diff --git a/core/tests/benchmarks/src/android/os/FileUtilsBenchmark.java b/core/tests/benchmarks/src/android/os/FileUtilsBenchmark.java
new file mode 100644
index 0000000..4f7c924
--- /dev/null
+++ b/core/tests/benchmarks/src/android/os/FileUtilsBenchmark.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.os;
+
+import static android.os.FileUtils.copyInternalSendfile;
+import static android.os.FileUtils.copyInternalSplice;
+import static android.os.FileUtils.copyInternalUserspace;
+
+import android.os.FileUtils.MemoryPipe;
+
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Param;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+public class FileUtilsBenchmark {
+ @Param({"32", "32000", "32000000"})
+ private int mSize;
+
+ private File mSrc;
+ private File mDest;
+
+ private byte[] mData;
+
+ @BeforeExperiment
+ protected void setUp() throws Exception {
+ mSrc = new File("/data/local/tmp/src");
+ mDest = new File("/data/local/tmp/dest");
+
+ mData = new byte[mSize];
+
+ try (FileOutputStream os = new FileOutputStream(mSrc)) {
+ os.write(mData);
+ }
+ }
+
+ public void timeRegularUserspace(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ try (FileInputStream in = new FileInputStream(mSrc);
+ FileOutputStream out = new FileOutputStream(mDest)) {
+ copyInternalUserspace(in.getFD(), out.getFD(), null, null);
+ }
+ }
+ }
+
+ public void timeRegularSendfile(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ try (FileInputStream in = new FileInputStream(mSrc);
+ FileOutputStream out = new FileOutputStream(mDest)) {
+ copyInternalSendfile(in.getFD(), out.getFD(), null, null);
+ }
+ }
+ }
+
+ public void timePipeSourceUserspace(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ try (MemoryPipe in = MemoryPipe.createSource(mData);
+ FileOutputStream out = new FileOutputStream(mDest)) {
+ copyInternalUserspace(in.getFD(), out.getFD(), null, null);
+ }
+ }
+ }
+
+ public void timePipeSourceSplice(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ try (MemoryPipe in = MemoryPipe.createSource(mData);
+ FileOutputStream out = new FileOutputStream(mDest)) {
+ copyInternalSplice(in.getFD(), out.getFD(), null, null);
+ }
+ }
+ }
+
+ public void timePipeSinkUserspace(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ try (FileInputStream in = new FileInputStream(mSrc);
+ MemoryPipe out = MemoryPipe.createSink(mData)) {
+ copyInternalUserspace(in.getFD(), out.getFD(), null, null);
+ }
+ }
+ }
+
+ public void timePipeSinkSplice(int reps) throws Exception {
+ for (int i = 0; i < reps; i++) {
+ try (FileInputStream in = new FileInputStream(mSrc);
+ MemoryPipe out = MemoryPipe.createSink(mData)) {
+ copyInternalSplice(in.getFD(), out.getFD(), null, null);
+ }
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index cd20192..b7220b3 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -21,16 +21,19 @@
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.content.Context;
+import android.os.FileUtils.MemoryPipe;
import android.provider.DocumentsContract.Document;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import libcore.io.IoUtils;
+import libcore.io.Streams;
import com.google.android.collect.Sets;
@@ -40,11 +43,13 @@
import org.junit.runner.RunWith;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.FileWriter;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.Random;
@RunWith(AndroidJUnit4.class)
public class FileUtilsTest {
@@ -56,6 +61,8 @@
private File mCopyFile;
private File mTarget;
+ private final int[] DATA_SIZES = { 32, 32_000, 32_000_000 };
+
private Context getContext() {
return InstrumentationRegistry.getContext();
}
@@ -80,7 +87,7 @@
@Test
public void testCopyFile() throws Exception {
- stageFile(mTestFile, TEST_DATA);
+ writeFile(mTestFile, TEST_DATA);
assertFalse(mCopyFile.exists());
FileUtils.copyFile(mTestFile, mCopyFile);
assertTrue(mCopyFile.exists());
@@ -97,6 +104,83 @@
}
@Test
+ public void testCopy_FileToFile() throws Exception {
+ for (int size : DATA_SIZES) {
+ final File src = new File(mTarget, "src");
+ final File dest = new File(mTarget, "dest");
+
+ byte[] expected = new byte[size];
+ byte[] actual = new byte[size];
+ new Random().nextBytes(expected);
+ writeFile(src, expected);
+
+ try (FileInputStream in = new FileInputStream(src);
+ FileOutputStream out = new FileOutputStream(dest)) {
+ FileUtils.copy(in, out);
+ }
+
+ actual = readFile(dest);
+ assertArrayEquals(expected, actual);
+ }
+ }
+
+ @Test
+ public void testCopy_FileToPipe() throws Exception {
+ for (int size : DATA_SIZES) {
+ final File src = new File(mTarget, "src");
+
+ byte[] expected = new byte[size];
+ byte[] actual = new byte[size];
+ new Random().nextBytes(expected);
+ writeFile(src, expected);
+
+ try (FileInputStream in = new FileInputStream(src);
+ MemoryPipe out = MemoryPipe.createSink(actual)) {
+ FileUtils.copy(in.getFD(), out.getFD());
+ out.join();
+ }
+
+ assertArrayEquals(expected, actual);
+ }
+ }
+
+ @Test
+ public void testCopy_PipeToFile() throws Exception {
+ for (int size : DATA_SIZES) {
+ final File dest = new File(mTarget, "dest");
+
+ byte[] expected = new byte[size];
+ byte[] actual = new byte[size];
+ new Random().nextBytes(expected);
+
+ try (MemoryPipe in = MemoryPipe.createSource(expected);
+ FileOutputStream out = new FileOutputStream(dest)) {
+ FileUtils.copy(in.getFD(), out.getFD());
+ }
+
+ actual = readFile(dest);
+ assertArrayEquals(expected, actual);
+ }
+ }
+
+ @Test
+ public void testCopy_PipeToPipe() throws Exception {
+ for (int size : DATA_SIZES) {
+ byte[] expected = new byte[size];
+ byte[] actual = new byte[size];
+ new Random().nextBytes(expected);
+
+ try (MemoryPipe in = MemoryPipe.createSource(expected);
+ MemoryPipe out = MemoryPipe.createSink(actual)) {
+ FileUtils.copy(in.getFD(), out.getFD());
+ out.join();
+ }
+
+ assertArrayEquals(expected, actual);
+ }
+ }
+
+ @Test
public void testIsFilenameSafe() throws Exception {
assertTrue(FileUtils.isFilenameSafe(new File("foobar")));
assertTrue(FileUtils.isFilenameSafe(new File("a_b-c=d.e/0,1+23")));
@@ -106,7 +190,7 @@
@Test
public void testReadTextFile() throws Exception {
- stageFile(mTestFile, TEST_DATA);
+ writeFile(mTestFile, TEST_DATA);
assertEquals(TEST_DATA, FileUtils.readTextFile(mTestFile, 0, null));
@@ -127,7 +211,7 @@
@Test
public void testReadTextFileWithZeroLengthFile() throws Exception {
- stageFile(mTestFile, TEST_DATA);
+ writeFile(mTestFile, TEST_DATA);
new FileOutputStream(mTestFile).close(); // Zero out the file
assertEquals("", FileUtils.readTextFile(mTestFile, 0, null));
assertEquals("", FileUtils.readTextFile(mTestFile, 1, "<>"));
@@ -381,12 +465,21 @@
file.setLastModified(System.currentTimeMillis() - age);
}
- private void stageFile(File file, String data) throws Exception {
- FileWriter writer = new FileWriter(file);
- try {
- writer.write(data, 0, data.length());
- } finally {
- writer.close();
+ private void writeFile(File file, String data) throws Exception {
+ writeFile(file, data.getBytes());
+ }
+
+ private void writeFile(File file, byte[] data) throws Exception {
+ try (FileOutputStream out = new FileOutputStream(file)) {
+ out.write(data);
+ }
+ }
+
+ private byte[] readFile(File file) throws Exception {
+ try (FileInputStream in = new FileInputStream(file);
+ ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+ Streams.copy(in, out);
+ return out.toByteArray();
}
}
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index d77e601..fe2b523 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -160,25 +160,6 @@
isItalic);
}
- /**
- * Allow creating unsupported FontFamily.
- *
- * For compatibility reasons, we still need to create a FontFamily object even if Minikin failed
- * to find any usable 'cmap' table for some reasons, e.g. broken 'cmap' table, no 'cmap' table
- * encoded with Unicode code points, etc. Without calling this method, the freeze() method will
- * return null if Minikin fails to find any usable 'cmap' table. By calling this method, the
- * freeze() won't fail and will create an empty FontFamily. This empty FontFamily is placed at
- * the top of the fallback chain but is never used. if we don't create this empty FontFamily
- * and put it at top, bad things (performance regressions, unexpected glyph selection) will
- * happen.
- */
- public void allowUnsupportedFont() {
- if (mBuilderPtr == 0) {
- throw new IllegalStateException("Unable to allow unsupported font.");
- }
- nAllowUnsupportedFont(mBuilderPtr);
- }
-
// TODO: Remove once internal user stop using private API.
private static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex) {
return nAddFont(builderPtr, font, ttcIndex, -1, -1);
@@ -190,9 +171,6 @@
private static native long nCreateFamily(long mBuilderPtr);
@CriticalNative
- private static native void nAllowUnsupportedFont(long builderPtr);
-
- @CriticalNative
private static native void nAbort(long mBuilderPtr);
@CriticalNative
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index ef41507..04c5295 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -818,12 +818,9 @@
if (fontFamily.addFontFromAssetManager(mgr, path, 0, true /* isAsset */,
0 /* ttc index */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE,
null /* axes */)) {
- // Due to backward compatibility, even if the font is not supported by our font
- // stack, we need to place the empty font at the first place. The typeface with
- // empty font behaves different from default typeface especially in fallback
- // font selection.
- fontFamily.allowUnsupportedFont();
- fontFamily.freeze();
+ if (!fontFamily.freeze()) {
+ return Typeface.DEFAULT;
+ }
final FontFamily[] families = { fontFamily };
typeface = createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
@@ -870,12 +867,9 @@
final FontFamily fontFamily = new FontFamily();
if (fontFamily.addFont(path, 0 /* ttcIndex */, null /* axes */,
RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)) {
- // Due to backward compatibility, even if the font is not supported by our font
- // stack, we need to place the empty font at the first place. The typeface with
- // empty font behaves different from default typeface especially in fallback font
- // selection.
- fontFamily.allowUnsupportedFont();
- fontFamily.freeze();
+ if (!fontFamily.freeze()) {
+ return Typeface.DEFAULT;
+ }
FontFamily[] families = { fontFamily };
return createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index bd49b87..27c8fda 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -348,7 +348,9 @@
if (mState == null) {
throw new IllegalStateException("called stop on empty AnimatedImageDrawable");
}
- nStop(mState.mNativePtr);
+ if (nStop(mState.mNativePtr)) {
+ postOnAnimationEnd();
+ }
}
// Animatable2 overrides
@@ -365,21 +367,31 @@
nSetOnAnimationEndListener(mState.mNativePtr, this);
}
- mAnimationCallbacks.add(callback);
+ if (!mAnimationCallbacks.contains(callback)) {
+ mAnimationCallbacks.add(callback);
+ }
}
@Override
public boolean unregisterAnimationCallback(@NonNull AnimationCallback callback) {
- if (callback == null || mAnimationCallbacks == null) {
+ if (callback == null || mAnimationCallbacks == null
+ || !mAnimationCallbacks.remove(callback)) {
return false;
}
- return mAnimationCallbacks.remove(callback);
+ if (mAnimationCallbacks.isEmpty()) {
+ clearAnimationCallbacks();
+ }
+
+ return true;
}
@Override
public void clearAnimationCallbacks() {
- mAnimationCallbacks = null;
+ if (mAnimationCallbacks != null) {
+ mAnimationCallbacks = null;
+ nSetOnAnimationEndListener(mState.mNativePtr, null);
+ }
}
private void postOnAnimationStart() {
@@ -413,6 +425,21 @@
return mHandler;
}
+ /**
+ * Called by JNI.
+ *
+ * The JNI code has already posted this to the thread that created the
+ * callback, so no need to post.
+ */
+ @SuppressWarnings("unused")
+ private void onAnimationEnd() {
+ if (mAnimationCallbacks != null) {
+ for (Animatable2.AnimationCallback callback : mAnimationCallbacks) {
+ callback.onAnimationEnd(this);
+ }
+ }
+ }
+
private static native long nCreate(long nativeImageDecoder,
@Nullable ImageDecoder decoder, int width, int height, Rect cropRect)
@@ -432,7 +459,7 @@
@FastNative
private static native boolean nStart(long nativePtr);
@FastNative
- private static native void nStop(long nativePtr);
+ private static native boolean nStop(long nativePtr);
@FastNative
private static native void nSetLoopCount(long nativePtr, int loopCount);
// Pass the drawable down to native so it can call onAnimationEnd.
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp
index 5356d3b..2bded9b 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.cpp
+++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp
@@ -48,8 +48,10 @@
return true;
}
-void AnimatedImageDrawable::stop() {
+bool AnimatedImageDrawable::stop() {
+ bool wasRunning = mRunning;
mRunning = false;
+ return wasRunning;
}
bool AnimatedImageDrawable::isRunning() {
@@ -180,7 +182,6 @@
if (finalFrame) {
if (mEndListener) {
mEndListener->onAnimationEnd();
- mEndListener = nullptr;
}
}
}
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.h b/libs/hwui/hwui/AnimatedImageDrawable.h
index 9d84ed5..2fd6f40 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.h
+++ b/libs/hwui/hwui/AnimatedImageDrawable.h
@@ -68,7 +68,9 @@
// Returns true if the animation was started; false otherwise (e.g. it was
// already running)
bool start();
- void stop();
+ // Returns true if the animation was stopped; false otherwise (e.g. it was
+ // already stopped)
+ bool stop();
bool isRunning();
void setRepetitionCount(int count) { mSkAnimatedImage->setRepetitionCount(count); }
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index 43f46ef..a0d000d 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -44,7 +44,6 @@
minikinPaint.familyVariant = paint->getFamilyVariant();
minikinPaint.fontStyle = resolvedFace->fStyle;
minikinPaint.fontFeatureSettings = paint->getFontFeatureSettings();
- minikinPaint.hyphenEdit = minikin::HyphenEdit(paint->getHyphenEdit());
return minikinPaint;
}
@@ -55,18 +54,23 @@
minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface);
minikin::Layout layout;
+ const minikin::U16StringPiece textBuf(buf, bufSize);
+ const minikin::Range range(start, start + count);
+ const minikin::HyphenEdit hyphenEdit = static_cast<minikin::HyphenEdit>(paint->getHyphenEdit());
+ const minikin::StartHyphenEdit startHyphen = minikin::startHyphenEdit(hyphenEdit);
+ const minikin::EndHyphenEdit endHyphen = minikin::endHyphenEdit(hyphenEdit);
+
if (mt == nullptr) {
- layout.doLayout(buf, start, count, bufSize, bidiFlags, minikinPaint);
+ layout.doLayout(textBuf,range, bidiFlags, minikinPaint, startHyphen, endHyphen);
return layout;
}
- if (mt->buildLayout(minikin::U16StringPiece(buf, bufSize),
- minikin::Range(start, start + count),
- minikinPaint, bidiFlags, mtOffset, &layout)) {
+ if (mt->buildLayout(textBuf, range, minikinPaint, bidiFlags, mtOffset, startHyphen, endHyphen,
+ &layout)) {
return layout;
}
- layout.doLayout(buf, start, count, bufSize, bidiFlags, minikinPaint);
+ layout.doLayout(textBuf, range, bidiFlags, minikinPaint, startHyphen, endHyphen);
return layout;
}
@@ -74,8 +78,14 @@
const Typeface* typeface, const uint16_t* buf, size_t start,
size_t count, size_t bufSize, float* advances) {
minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface);
- return minikin::Layout::measureText(buf, start, count, bufSize, bidiFlags, minikinPaint,
- advances, nullptr /* extent */);
+ const minikin::U16StringPiece textBuf(buf, bufSize);
+ const minikin::Range range(start, start + count);
+ const minikin::HyphenEdit hyphenEdit = static_cast<minikin::HyphenEdit>(paint->getHyphenEdit());
+ const minikin::StartHyphenEdit startHyphen = minikin::startHyphenEdit(hyphenEdit);
+ const minikin::EndHyphenEdit endHyphen = minikin::endHyphenEdit(hyphenEdit);
+
+ return minikin::Layout::measureText(textBuf, range, bidiFlags, minikinPaint, startHyphen,
+ endHyphen, advances, nullptr /* extent */);
}
bool MinikinUtils::hasVariationSelector(const Typeface* typeface, uint32_t codepoint, uint32_t vs) {
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 018db9a..fa3f99a 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -88,11 +88,6 @@
boolean providerMeetsCriteria(String provider, in Criteria criteria);
ProviderProperties getProviderProperties(String provider);
String getNetworkProviderPackage();
- boolean isProviderEnabled(String provider);
- boolean isProviderEnabledForUser(String provider, int userId);
- boolean setProviderEnabledForUser(String provider, boolean enabled, int userId);
- boolean isLocationEnabledForUser(int userId);
- void setLocationEnabledForUser(boolean enabled, int userId);
void addTestProvider(String name, in ProviderProperties properties, String opPackageName);
void removeTestProvider(String provider, String opPackageName);
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index b07d042..f98480b 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -265,6 +265,12 @@
public static final int ENCODING_AAC_XHE = 16;
/** Audio data format: AC-4 sync frame transport format */
public static final int ENCODING_AC4 = 17;
+ /** Audio data format: E-AC-3-JOC compressed
+ * E-AC-3-JOC streams can be decoded by downstream devices supporting {@link #ENCODING_E_AC3}.
+ * Use {@link #ENCODING_E_AC3} as the AudioTrack encoding when the downstream device
+ * supports {@link #ENCODING_E_AC3} but not {@link #ENCODING_E_AC3_JOC}.
+ **/
+ public static final int ENCODING_E_AC3_JOC = 18;
/** @hide */
public static String toLogFriendlyEncoding(int enc) {
@@ -512,6 +518,7 @@
case ENCODING_PCM_FLOAT:
case ENCODING_AC3:
case ENCODING_E_AC3:
+ case ENCODING_E_AC3_JOC:
case ENCODING_DTS:
case ENCODING_DTS_HD:
case ENCODING_MP3:
@@ -537,6 +544,7 @@
case ENCODING_PCM_FLOAT:
case ENCODING_AC3:
case ENCODING_E_AC3:
+ case ENCODING_E_AC3_JOC:
case ENCODING_DTS:
case ENCODING_DTS_HD:
case ENCODING_IEC61937:
@@ -564,6 +572,7 @@
return true;
case ENCODING_AC3:
case ENCODING_E_AC3:
+ case ENCODING_E_AC3_JOC:
case ENCODING_DTS:
case ENCODING_DTS_HD:
case ENCODING_MP3:
@@ -593,6 +602,7 @@
return true;
case ENCODING_AC3:
case ENCODING_E_AC3:
+ case ENCODING_E_AC3_JOC:
case ENCODING_DTS:
case ENCODING_DTS_HD:
case ENCODING_MP3:
@@ -829,6 +839,7 @@
case ENCODING_PCM_FLOAT:
case ENCODING_AC3:
case ENCODING_E_AC3:
+ case ENCODING_E_AC3_JOC:
case ENCODING_DTS:
case ENCODING_DTS_HD:
case ENCODING_IEC61937:
@@ -1044,6 +1055,7 @@
ENCODING_PCM_FLOAT,
ENCODING_AC3,
ENCODING_E_AC3,
+ ENCODING_E_AC3_JOC,
ENCODING_DTS,
ENCODING_DTS_HD,
ENCODING_IEC61937,
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 3eb9d52..fefa1ed 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -28,11 +28,13 @@
import android.content.ContentUris;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.database.Cursor;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
@@ -47,22 +49,17 @@
import com.android.internal.database.SortCursor;
-import libcore.io.Streams;
-
import java.io.Closeable;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
-import static android.content.ContentProvider.maybeAddUserId;
-import static android.content.pm.PackageManager.NameNotFoundException;
-
/**
* RingtoneManager provides access to ringtones, notification, and other types
* of sounds. It manages querying the different media providers and combines the
@@ -855,7 +852,7 @@
final Uri cacheUri = getCacheForType(type, context.getUserId());
try (InputStream in = openRingtone(context, ringtoneUri);
OutputStream out = resolver.openOutputStream(cacheUri)) {
- Streams.copy(in, out);
+ FileUtils.copy(in, out);
} catch (IOException e) {
Log.w(TAG, "Failed to cache ringtone: " + e);
}
@@ -960,7 +957,7 @@
// Copy contents to external ringtone storage. Throws IOException if the copy fails.
try (final InputStream input = mContext.getContentResolver().openInputStream(fileUri);
final OutputStream output = new FileOutputStream(outFile)) {
- Streams.copy(input, output);
+ FileUtils.copy(input, output);
}
// Tell MediaScanner about the new file. Wait for it to assign a {@link Uri}.
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 8b01aef..9f165bc 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -30,6 +30,7 @@
import android.content.res.ObbScanner;
import android.os.Binder;
import android.os.Environment.UserEnvironment;
+import android.os.FileUtils;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.Process;
@@ -43,7 +44,6 @@
import com.android.internal.util.ArrayUtils;
import libcore.io.IoUtils;
-import libcore.io.Streams;
import java.io.File;
import java.io.FileInputStream;
@@ -260,7 +260,7 @@
in = new FileInputStream(sourcePath);
out = new ParcelFileDescriptor.AutoCloseOutputStream(
target.open(targetName, ParcelFileDescriptor.MODE_READ_WRITE));
- Streams.copy(in, out);
+ FileUtils.copy(in, out);
} finally {
IoUtils.closeQuietly(out);
IoUtils.closeQuietly(in);
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixin.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixin.java
index 7983896..c23f226 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixin.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixin.java
@@ -17,21 +17,20 @@
package com.android.settingslib.core.instrumentation;
import android.app.Activity;
-import android.content.Context;
+import android.arch.lifecycle.Lifecycle.Event;
+import android.arch.lifecycle.LifecycleObserver;
+import android.arch.lifecycle.OnLifecycleEvent;
import android.content.Intent;
import android.os.SystemClock;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
import static com.android.settingslib.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
/**
* Logs visibility change of a fragment.
*/
-public class VisibilityLoggerMixin implements LifecycleObserver, OnResume, OnPause {
+public class VisibilityLoggerMixin implements LifecycleObserver {
private static final String TAG = "VisibilityLoggerMixin";
@@ -55,7 +54,7 @@
mMetricsFeature = metricsFeature;
}
- @Override
+ @OnLifecycleEvent(Event.ON_RESUME)
public void onResume() {
mVisibleTimestamp = SystemClock.elapsedRealtime();
if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
@@ -63,7 +62,7 @@
}
}
- @Override
+ @OnLifecycleEvent(Event.ON_PAUSE)
public void onPause() {
mVisibleTimestamp = 0;
if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
index a264886..1ab6afe 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
@@ -18,6 +18,7 @@
import static com.android.settingslib.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;
import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
@@ -30,6 +31,8 @@
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
import com.android.settingslib.TestConfig;
@@ -39,6 +42,8 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
@@ -110,6 +115,30 @@
.hidden(nullable(Context.class), anyInt());
}
+ @Test
+ public void activityShouldBecomeVisibleAndHide() {
+ ActivityController<TestActivity> ac = Robolectric.buildActivity(TestActivity.class);
+ TestActivity testActivity = ac.get();
+ MockitoAnnotations.initMocks(testActivity);
+ ac.create().start().resume();
+ verify(testActivity.mMetricsFeatureProvider, times(1)).visible(any(), anyInt(), anyInt());
+ ac.pause().stop().destroy();
+ verify(testActivity.mMetricsFeatureProvider, times(1)).hidden(any(), anyInt());
+ }
+
+ public static class TestActivity extends FragmentActivity {
+ @Mock
+ MetricsFeatureProvider mMetricsFeatureProvider;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ VisibilityLoggerMixin mixin = new VisibilityLoggerMixin(
+ TestInstrumentable.TEST_METRIC, mMetricsFeatureProvider);
+ getLifecycle().addObserver(mixin);
+ super.onCreate(savedInstanceState);
+ }
+ }
+
private final class TestInstrumentable implements Instrumentable {
public static final int TEST_METRIC = 12345;
diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml
index a3118b0..c2b1009 100644
--- a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml
+++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml
@@ -84,25 +84,7 @@
android:layout_height="@dimen/screen_pinning_request_button_height"
android:layout_weight="0"
android:paddingStart="@dimen/screen_pinning_request_frame_padding"
- android:paddingEnd="@dimen/screen_pinning_request_frame_padding"
- android:theme="@*android:style/ThemeOverlay.DeviceDefault.Accent">
-
- <ImageView
- android:id="@+id/screen_pinning_home_bg_light"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="matrix"
- android:src="@drawable/screen_pinning_light_bg_circ" />
-
- <ImageView
- android:id="@+id/screen_pinning_home_bg"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingEnd="@dimen/screen_pinning_request_inner_padding"
- android:paddingStart="@dimen/screen_pinning_request_inner_padding"
- android:paddingTop="@dimen/screen_pinning_request_inner_padding"
- android:scaleType="matrix"
- android:src="@drawable/screen_pinning_bg_circ" />
+ android:paddingEnd="@dimen/screen_pinning_request_frame_padding" >
<ImageView
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index fadcbcd..5557f8e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1281,23 +1281,12 @@
<string name="screen_pinning_title">Screen is pinned</string>
<!-- Screen pinning dialog description. -->
<string name="screen_pinning_description">This keeps it in view until you unpin. Touch & hold Back and Overview to unpin.</string>
- <string name="screen_pinning_description_recents_invisible">This keeps it in view until you unpin. Touch & hold Back and Home to unpin.</string>
<!-- Screen pinning dialog description. -->
<string name="screen_pinning_description_accessible">This keeps it in view until you unpin. Touch & hold Overview to unpin.</string>
- <string name="screen_pinning_description_recents_invisible_accessible">This keeps it in view until you unpin. Touch & hold Home to unpin.</string>
- <!-- Notify use that they are in Lock-to-app -->
- <string name="screen_pinning_toast">To unpin this screen, touch & hold Back and Overview
- buttons</string>
- <string name="screen_pinning_toast_recents_invisible">To unpin this screen, touch & hold Back
- and Home buttons</string>
<!-- Screen pinning positive response. -->
<string name="screen_pinning_positive">Got it</string>
<!-- Screen pinning negative response. -->
<string name="screen_pinning_negative">No thanks</string>
- <!-- Enter/Exiting screen pinning indication. -->
- <string name="screen_pinning_start">Screen pinned</string>
- <string name="screen_pinning_exit">Screen unpinned</string>
-
<!-- Hide quick settings tile confirmation title -->
<string name="quick_settings_reset_confirmation_title">Hide <xliff:g id="tile_label" example="Hotspot">%1$s</xliff:g>?</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SysUIToast.java b/packages/SystemUI/src/com/android/systemui/SysUIToast.java
index 43b918d..89bc82f 100644
--- a/packages/SystemUI/src/com/android/systemui/SysUIToast.java
+++ b/packages/SystemUI/src/com/android/systemui/SysUIToast.java
@@ -15,19 +15,13 @@
*/
package com.android.systemui;
-import android.annotation.StringRes;
import android.content.Context;
import android.view.WindowManager;
import android.widget.Toast;
-import static android.widget.Toast.Duration;
public class SysUIToast {
- public static Toast makeText(Context context, @StringRes int resId, @Duration int duration) {
- return makeText(context, context.getString(resId), duration);
- }
-
- public static Toast makeText(Context context, CharSequence text, @Duration int duration) {
+ public static Toast makeText(Context context, CharSequence text, int duration) {
Toast toast = Toast.makeText(context, text, duration);
toast.getWindowParams().privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 6b0d592..6ccb817 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -36,7 +36,6 @@
public class QSContainerImpl extends FrameLayout {
private final Point mSizePoint = new Point();
- private final Path mClipPath = new Path();
private int mHeightOverride = -1;
protected View mQSPanel;
@@ -46,7 +45,6 @@
private QSCustomizer mQSCustomizer;
private View mQSFooter;
private View mBackground;
- private float mRadius;
private int mSideMargins;
public QSContainerImpl(Context context, AttributeSet attrs) {
@@ -62,8 +60,6 @@
mQSCustomizer = findViewById(R.id.qs_customize);
mQSFooter = findViewById(R.id.qs_footer);
mBackground = findViewById(R.id.quick_settings_background);
- mRadius = getResources().getDimensionPixelSize(
- Utils.getThemeAttr(mContext, android.R.attr.dialogCornerRadius));
mSideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
setClickable(true);
@@ -115,18 +111,6 @@
updateExpansion();
}
- @Override
- protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
- boolean ret;
- canvas.save();
- if (child != mQSCustomizer) {
- canvas.clipPath(mClipPath);
- }
- ret = super.drawChild(canvas, child, drawingTime);
- canvas.restore();
- return ret;
- }
-
/**
* Overrides the height of this view (post-layout), so that the content is clipped to that
* height and the background is set to that height.
@@ -146,10 +130,6 @@
mQSFooter.setTranslationY(height - mQSFooter.getHeight());
mBackground.setTop(mQSPanel.getTop());
mBackground.setBottom(height);
-
- ExpandableOutlineView.getRoundedRectPath(0, 0, getWidth(), height, mRadius,
- mRadius,
- mClipPath);
}
protected int calculateContainerHeight() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 57f7818..316ad16 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -23,12 +23,15 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Configuration;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.os.Binder;
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.view.Gravity;
+import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -40,9 +43,6 @@
import android.widget.TextView;
import com.android.systemui.R;
-import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.statusbar.phone.NavigationBarView;
-import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.leak.RotationUtils;
import java.util.ArrayList;
@@ -233,30 +233,11 @@
.setVisibility(View.INVISIBLE);
}
- StatusBar statusBar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
- NavigationBarView navigationBarView = statusBar.getNavigationBarView();
- final boolean recentsVisible = navigationBarView != null
- && navigationBarView.isRecentsButtonVisible();
boolean touchExplorationEnabled = mAccessibilityService.isTouchExplorationEnabled();
- int descriptionStringResId;
- if (recentsVisible) {
- mLayout.findViewById(R.id.screen_pinning_recents_group).setVisibility(VISIBLE);
- mLayout.findViewById(R.id.screen_pinning_home_bg_light).setVisibility(INVISIBLE);
- mLayout.findViewById(R.id.screen_pinning_home_bg).setVisibility(INVISIBLE);
- descriptionStringResId = touchExplorationEnabled
- ? R.string.screen_pinning_description_accessible
- : R.string.screen_pinning_description;
- } else {
- mLayout.findViewById(R.id.screen_pinning_recents_group).setVisibility(INVISIBLE);
- mLayout.findViewById(R.id.screen_pinning_home_bg_light).setVisibility(VISIBLE);
- mLayout.findViewById(R.id.screen_pinning_home_bg).setVisibility(VISIBLE);
- descriptionStringResId = touchExplorationEnabled
- ? R.string.screen_pinning_description_recents_invisible_accessible
- : R.string.screen_pinning_description_recents_invisible;
- }
-
((TextView) mLayout.findViewById(R.id.screen_pinning_description))
- .setText(descriptionStringResId);
+ .setText(touchExplorationEnabled
+ ? R.string.screen_pinning_description_accessible
+ : R.string.screen_pinning_description);
final int backBgVisibility = touchExplorationEnabled ? View.INVISIBLE : View.VISIBLE;
mLayout.findViewById(R.id.screen_pinning_back_bg).setVisibility(backBgVisibility);
mLayout.findViewById(R.id.screen_pinning_back_bg_light).setVisibility(backBgVisibility);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index f5f62b85..79e9f7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -24,7 +24,6 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
-import android.os.RemoteException;
import android.support.annotation.VisibleForTesting;
import android.util.Pair;
@@ -91,8 +90,6 @@
private static final int MSG_FINGERPRINT_ERROR = 42 << MSG_SHIFT;
private static final int MSG_FINGERPRINT_HIDE = 43 << MSG_SHIFT;
private static final int MSG_SHOW_CHARGING_ANIMATION = 44 << MSG_SHIFT;
- private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT = 45 << MSG_SHIFT;
- private static final int MSG_SHOW_PINNING_TOAST_ESCAPE = 46 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -151,8 +148,6 @@
default void clickTile(ComponentName tile) { }
default void handleSystemKey(int arg1) { }
- default void showPinningEnterExitToast(boolean entering) { }
- default void showPinningEscapeToast() { }
default void handleShowGlobalActionsMenu() { }
default void handleShowShutdownUi(boolean isReboot, String reason) { }
@@ -458,21 +453,6 @@
}
@Override
- public void showPinningEnterExitToast(boolean entering) {
- synchronized (mLock) {
- mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ENTER_EXIT, entering).sendToTarget();
- }
- }
-
- @Override
- public void showPinningEscapeToast() {
- synchronized (mLock) {
- mHandler.obtainMessage(MSG_SHOW_PINNING_TOAST_ESCAPE).sendToTarget();
- }
- }
-
-
- @Override
public void showGlobalActionsMenu() {
synchronized (mLock) {
mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS);
@@ -787,16 +767,6 @@
mCallbacks.get(i).showChargingAnimation(msg.arg1);
}
break;
- case MSG_SHOW_PINNING_TOAST_ENTER_EXIT:
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).showPinningEnterExitToast(msg.arg1 != 0);
- }
- break;
- case MSG_SHOW_PINNING_TOAST_ESCAPE:
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).showPinningEscapeToast();
- }
- break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 242be71..65c45a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -22,13 +22,11 @@
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE;
import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions;
-import static com.android.systemui.OverviewProxyService.OverviewProxyListener;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
-import android.annotation.IdRes;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -71,7 +69,6 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
-import android.widget.Button;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -156,18 +153,6 @@
private Animator mRotateShowAnimator;
private Animator mRotateHideAnimator;
- private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
- @Override
- public void onConnectionChanged(boolean isConnected) {
- mNavigationBarView.onOverviewProxyConnectionChanged(isConnected);
- updateScreenPinningGestures();
- }
-
- @Override
- public void onRecentsAnimationStarted() {
- mNavigationBarView.setRecentsAnimationStarted(true);
- }
- };
// ----- Fragment Lifecycle Callbacks -----
@@ -254,14 +239,12 @@
filter.addAction(Intent.ACTION_SCREEN_ON);
getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
notifyNavigationBarScreenOn();
- mOverviewProxyService.addCallback(mOverviewProxyListener);
}
@Override
public void onDestroyView() {
super.onDestroyView();
mNavigationBarView.getLightTransitionsController().destroy(getContext());
- mOverviewProxyService.removeCallback(mOverviewProxyListener);
getContext().unregisterReceiver(mBroadcastReceiver);
}
@@ -531,7 +514,6 @@
if (masked != mDisabledFlags1) {
mDisabledFlags1 = masked;
if (mNavigationBarView != null) mNavigationBarView.setDisabledFlags(state1);
- updateScreenPinningGestures();
}
}
@@ -546,7 +528,7 @@
private boolean shouldDisableNavbarGestures() {
return !mStatusBar.isDeviceProvisioned()
|| (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0
- || mNavigationBarView.getRecentsButton().getVisibility() != View.VISIBLE;
+ || mOverviewProxyService.getProxy() != null;
}
private void repositionNavigationBar() {
@@ -558,24 +540,6 @@
((View) mNavigationBarView.getParent()).getLayoutParams());
}
- private void updateScreenPinningGestures() {
- if (mNavigationBarView == null) {
- return;
- }
-
- // Change the cancel pin gesture to home and back if recents button is invisible
- boolean recentsVisible = mNavigationBarView.isRecentsButtonVisible();
- ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
- ButtonDispatcher backButton = mNavigationBarView.getBackButton();
- if (recentsVisible) {
- homeButton.setOnLongClickListener(this::onHomeLongClick);
- backButton.setOnLongClickListener(this::onLongPressBackRecents);
- } else {
- homeButton.setOnLongClickListener(this::onLongPressBackHome);
- backButton.setOnLongClickListener(this::onLongPressBackHome);
- }
- }
-
private void notifyNavigationBarScreenOn() {
mNavigationBarView.notifyScreenOn();
}
@@ -685,29 +649,20 @@
mCommandQueue.toggleRecentApps();
}
- private boolean onLongPressBackHome(View v) {
- return onLongPressNavigationButtons(v, R.id.back, R.id.home);
- }
-
- private boolean onLongPressBackRecents(View v) {
- return onLongPressNavigationButtons(v, R.id.back, R.id.recent_apps);
- }
-
/**
- * This handles long-press of both back and recents/home. Back is the common button with
- * combination of recents if it is visible or home if recents is invisible.
- * They are handled together to capture them both being long-pressed
+ * This handles long-press of both back and recents. They are
+ * handled together to capture them both being long-pressed
* at the same time to exit screen pinning (lock task).
*
- * When accessibility mode is on, only a long-press from recents/home
+ * When accessibility mode is on, only a long-press from recents
* is required to exit.
*
* In all other circumstances we try to pass through long-press events
* for Back, so that apps can still use it. Which can be from two things.
* 1) Not currently in screen pinning (lock task).
- * 2) Back is long-pressed without recents/home.
+ * 2) Back is long-pressed without recents.
*/
- private boolean onLongPressNavigationButtons(View v, @IdRes int btnId1, @IdRes int btnId2) {
+ private boolean onLongPressBackRecents(View v) {
try {
boolean sendBackLongPress = false;
IActivityManager activityManager = ActivityManagerNative.getDefault();
@@ -715,7 +670,6 @@
boolean inLockTaskMode = activityManager.isInLockTaskMode();
if (inLockTaskMode && !touchExplorationEnabled) {
long time = System.currentTimeMillis();
-
// If we recently long-pressed the other button then they were
// long-pressed 'together'
if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERENCE) {
@@ -723,32 +677,26 @@
// When exiting refresh disabled flags.
mNavigationBarView.setDisabledFlags(mDisabledFlags1, true);
return true;
- } else if (v.getId() == btnId1) {
- ButtonDispatcher button = btnId2 == R.id.recent_apps
- ? mNavigationBarView.getRecentsButton()
- : mNavigationBarView.getHomeButton();
- if (!button.getCurrentView().isPressed()) {
- // If we aren't pressing recents/home right now then they presses
- // won't be together, so send the standard long-press action.
- sendBackLongPress = true;
- }
+ } else if ((v.getId() == R.id.back)
+ && !mNavigationBarView.getRecentsButton().getCurrentView().isPressed()) {
+ // If we aren't pressing recents right now then they presses
+ // won't be together, so send the standard long-press action.
+ sendBackLongPress = true;
}
mLastLockToAppLongPress = time;
} else {
// If this is back still need to handle sending the long-press event.
- if (v.getId() == btnId1) {
+ if (v.getId() == R.id.back) {
sendBackLongPress = true;
} else if (touchExplorationEnabled && inLockTaskMode) {
- // When in accessibility mode a long press that is recents/home (not back)
+ // When in accessibility mode a long press that is recents (not back)
// should stop lock task.
activityManager.stopSystemLockTaskMode();
// When exiting refresh disabled flags.
mNavigationBarView.setDisabledFlags(mDisabledFlags1, true);
return true;
- } else if (v.getId() == btnId2) {
- return btnId2 == R.id.recent_apps
- ? onLongPressRecents()
- : onHomeLongClick(mNavigationBarView.getHomeButton().getCurrentView());
+ } else if (v.getId() == R.id.recent_apps) {
+ return onLongPressRecents();
}
}
if (sendBackLongPress) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index cd220a7..e04ba83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -207,6 +207,23 @@
}
}
+ private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
+ @Override
+ public void onConnectionChanged(boolean isConnected) {
+ updateSlippery();
+ setDisabledFlags(mDisabledFlags, true);
+ setUpSwipeUpOnboarding(isConnected);
+ }
+
+ @Override
+ public void onRecentsAnimationStarted() {
+ mRecentsAnimationStarted = true;
+ if (mSwipeUpOnboarding != null) {
+ mSwipeUpOnboarding.onRecentsAnimationStarted();
+ }
+ }
+ };
+
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -263,19 +280,6 @@
notifyVerticalChangedListener(mVertical);
}
- public void setRecentsAnimationStarted(boolean started) {
- mRecentsAnimationStarted = started;
- if (mSwipeUpOnboarding != null) {
- mSwipeUpOnboarding.onRecentsAnimationStarted();
- }
- }
-
- public void onConnectionChanged(boolean isConnected) {
- updateSlippery();
- setDisabledFlags(mDisabledFlags, true);
- setUpSwipeUpOnboarding(isConnected);
- }
-
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mGestureHelper.onTouchEvent(event)) {
@@ -300,7 +304,7 @@
}
}
}
- return mRecentsAnimationStarted || mGestureHelper.onInterceptTouchEvent(event);
+ return mGestureHelper.onInterceptTouchEvent(event) || mRecentsAnimationStarted;
}
public void abortCurrentGesture() {
@@ -349,10 +353,6 @@
return mButtonDispatchers;
}
- public boolean isRecentsButtonVisible() {
- return getRecentsButton().getVisibility() == View.VISIBLE;
- }
-
private void updateCarModeIcons(Context ctx) {
mBackCarModeIcon = getDrawable(ctx,
R.drawable.ic_sysbar_back_carmode, R.drawable.ic_sysbar_back_carmode);
@@ -613,9 +613,6 @@
final ViewGroup navbarView = ((ViewGroup) getParent());
final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView
.getLayoutParams();
- if (lp == null) {
- return;
- }
if (slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) == 0) {
lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
changed = true;
@@ -679,12 +676,6 @@
}
}
- public void onOverviewProxyConnectionChanged(boolean isConnected) {
- setSlippery(!isConnected);
- setDisabledFlags(mDisabledFlags, true);
- setUpSwipeUpOnboarding(isConnected);
- }
-
@Override
protected void onDraw(Canvas canvas) {
mGestureHelper.onDraw(canvas);
@@ -882,6 +873,7 @@
onPluginDisconnected(null); // Create default gesture helper
Dependency.get(PluginManager.class).addPluginListener(this,
NavGesture.class, false /* Only one */);
+ mOverviewProxyService.addCallback(mOverviewProxyListener);
setUpSwipeUpOnboarding(mOverviewProxyService.getProxy() != null);
}
@@ -892,6 +884,7 @@
if (mGestureHelper != null) {
mGestureHelper.destroy();
}
+ mOverviewProxyService.removeCallback(mOverviewProxyListener);
setUpSwipeUpOnboarding(false);
}
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 1bf719a..426268b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -404,13 +404,6 @@
protected NotificationEntryManager mEntryManager;
protected NotificationViewHierarchyManager mViewHierarchyManager;
- /**
- * Helper that is responsible for showing the right toast when a disallowed activity operation
- * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
- * fully locked mode we only show that unlocking is blocked.
- */
- private ScreenPinningNotify mScreenPinningNotify;
-
// for disabling the status bar
private int mDisabled1 = 0;
private int mDisabled2 = 0;
@@ -837,7 +830,7 @@
} catch (RemoteException ex) {
// no window manager? good luck with that
}
- mScreenPinningNotify = new ScreenPinningNotify(mContext);
+
mStackScroller.setLongPressListener(mEntryManager.getNotificationLongClicker());
mStackScroller.setStatusBar(this);
mStackScroller.setGroupManager(mGroupManager);
@@ -2148,21 +2141,6 @@
}
- @Override
- public void showPinningEnterExitToast(boolean entering) {
- if (entering) {
- mScreenPinningNotify.showPinningStartToast();
- } else {
- mScreenPinningNotify.showPinningExitToast();
- }
- }
-
- @Override
- public void showPinningEscapeToast() {
- mScreenPinningNotify.showEscapeToast(getNavigationBarView() == null
- || getNavigationBarView().isRecentsButtonVisible());
- }
-
boolean panelsEnabled() {
return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0
&& (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/OutputChooserDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/OutputChooserDialogTest.java
index c18ed73..f7bb065 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/OutputChooserDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/OutputChooserDialogTest.java
@@ -44,11 +44,13 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+@Ignore
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -87,7 +89,7 @@
public void tearDown() throws Exception {
TestableLooper.get(this).processAllMessages();
}
-
+/*
@Test
public void testClickMediaRouterItemConnectsMedia() {
mDialog.show();
@@ -137,7 +139,7 @@
.getText().toString().contains("Phone"));
mDialog.dismiss();
}
-
+*/
@Test
public void testNoMediaScanIfInCall() {
mDialog.setIsInCall(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 4888fb2..43d60e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -48,6 +48,7 @@
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -55,6 +56,7 @@
import java.util.function.Predicate;
+@Ignore
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -111,7 +113,7 @@
+ " failed test", condition.test(view));
}
}
-
+/*
@Test
public void testContentDescriptions() {
mDialog.show(SHOW_REASON_UNKNOWN);
@@ -218,4 +220,5 @@
verify(mController, times(1)).setRingerMode(RINGER_MODE_NORMAL, false);
verify(mController, times(1)).setStreamVolume(STREAM_RING, 0);
}
+ */
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/ZenModePanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/ZenModePanelTest.java
deleted file mode 100644
index 4ab2063..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/ZenModePanelTest.java
+++ /dev/null
@@ -1,220 +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.systemui.volume;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.net.Uri;
-import android.provider.Settings;
-import android.service.notification.Condition;
-import android.service.notification.ZenModeConfig;
-import android.support.test.annotation.UiThreadTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.FlakyTest;
-import android.view.LayoutInflater;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.policy.ZenModeController;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@Ignore
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ZenModePanelTest extends SysuiTestCase {
-
- ZenModePanel mPanel;
- ZenModeController mController;
- Uri mForeverId;
-
- @Before
- public void setup() throws Exception {
- final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
- mPanel = (ZenModePanel) layoutInflater.inflate(com.android.systemui.R.layout.zen_mode_panel,
- null);
- mController = mock(ZenModeController.class);
- mForeverId = Condition.newId(mContext).appendPath("forever").build();
-
- mPanel.init(mController);
- }
-
- private void assertProperConditionTagTypes(boolean hasAlarm) {
- final int N = mPanel.getVisibleConditions();
- assertEquals(hasAlarm ? 3 : 2, N);
-
- assertEquals(mForeverId, mPanel.getConditionTagAt(0).condition.id);
- assertTrue(ZenModeConfig.isValidCountdownConditionId(
- mPanel.getConditionTagAt(1).condition.id));
- assertFalse(ZenModeConfig.isValidCountdownToAlarmConditionId(
- mPanel.getConditionTagAt(1).condition.id));
- if (hasAlarm) {
- assertTrue(ZenModeConfig.isValidCountdownToAlarmConditionId(
- mPanel.getConditionTagAt(2).condition.id));
- }
- }
-
- @Test
- public void testHandleUpdateConditions_foreverSelected_alarmExists() {
- Condition forever = new Condition(mForeverId, "", Condition.STATE_TRUE);
-
- when(mController.getNextAlarm()).thenReturn(System.currentTimeMillis() + 1000);
-
- mPanel.handleUpdateConditions(forever);
- assertProperConditionTagTypes(true);
- assertTrue(mPanel.getConditionTagAt(0).rb.isChecked());
- }
-
- @Test
- public void testHandleUpdateConditions_foreverSelected_noAlarm() {
- Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
- Condition forever = new Condition(foreverId, "", Condition.STATE_TRUE);
-
- when(mController.getNextAlarm()).thenReturn((long) 0);
-
- mPanel.handleUpdateConditions(forever);
- assertProperConditionTagTypes(false);
- assertEquals(foreverId, mPanel.getConditionTagAt(0).condition.id);
- }
-
- @Test
- public void testHandleUpdateConditions_countdownSelected_alarmExists() {
- Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
-
- Condition countdown = new Condition(ZenModeConfig.toCountdownConditionId(
- System.currentTimeMillis() + (3 * 60 * 60 * 1000) + 4000, false),
- "", Condition.STATE_TRUE);
-
- when(mController.getNextAlarm()).thenReturn(System.currentTimeMillis() + 1000);
-
- mPanel.handleUpdateConditions(countdown);
- assertProperConditionTagTypes(true);
- assertTrue(mPanel.getConditionTagAt(1).rb.isChecked());
- }
-
- @Test
- public void testHandleUpdateConditions_countdownSelected_noAlarm() {
- Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
-
- Condition countdown = new Condition(ZenModeConfig.toCountdownConditionId(
- System.currentTimeMillis() + (3 * 60 * 60 * 1000) + 4000, false),
- "", Condition.STATE_TRUE);
-
- when(mController.getNextAlarm()).thenReturn((long) 0);
-
- mPanel.handleUpdateConditions(countdown);
- assertProperConditionTagTypes(false);
- assertTrue(mPanel.getConditionTagAt(1).rb.isChecked());
- }
-
- @Test
- public void testHandleUpdateConditions_nextAlarmSelected() {
- Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
-
- Condition alarm = new Condition(ZenModeConfig.toCountdownConditionId(
- System.currentTimeMillis() + 1000, true),
- "", Condition.STATE_TRUE);
- when(mController.getNextAlarm()).thenReturn(System.currentTimeMillis() + 9000);
-
- mPanel.handleUpdateConditions(alarm);
-
- assertProperConditionTagTypes(true);
- assertEquals(alarm, mPanel.getConditionTagAt(2).condition);
- assertTrue(mPanel.getConditionTagAt(2).rb.isChecked());
- }
-
- @Test
- public void testHandleUpdateConditions_foreverSelected_alarmConditionDoesNotChangeIfAttached() {
- Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
- Condition forever = new Condition(foreverId, "", Condition.STATE_TRUE);
-
- Condition alarm = new Condition(ZenModeConfig.toCountdownConditionId(
- System.currentTimeMillis() + 9000, true),
- "", Condition.STATE_TRUE);
- when(mController.getNextAlarm()).thenReturn(System.currentTimeMillis() + 1000);
-
- mPanel.handleUpdateConditions(alarm);
- mPanel.setAttached(true);
- mPanel.handleUpdateConditions(forever);
-
- assertProperConditionTagTypes(true);
- assertEquals(alarm, mPanel.getConditionTagAt(2).condition);
- assertTrue(mPanel.getConditionTagAt(0).rb.isChecked());
- }
-
- @Test
- public void testHandleUpdateConditions_foreverSelected_timeConditionDoesNotChangeIfAttached() {
- Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
- Condition forever = new Condition(foreverId, "", Condition.STATE_TRUE);
-
- Condition countdown = new Condition(ZenModeConfig.toCountdownConditionId(
- System.currentTimeMillis() + (3 * 60 * 60 * 1000) + 4000, false),
- "", Condition.STATE_TRUE);
- when(mController.getNextAlarm()).thenReturn((long) 0);
-
- mPanel.handleUpdateConditions(countdown);
- mPanel.setAttached(true);
- mPanel.handleUpdateConditions(forever);
-
- assertProperConditionTagTypes(false);
- assertEquals(countdown, mPanel.getConditionTagAt(1).condition);
- assertTrue(mPanel.getConditionTagAt(0).rb.isChecked());
- }
-
- @Test
- @UiThreadTest
- public void testHandleUpdateManualRule_stillSelectedAfterModeChange() {
- ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
-
- Condition alarm = new Condition(ZenModeConfig.toCountdownConditionId(
- System.currentTimeMillis() + 1000, true),
- "", Condition.STATE_TRUE);
-
- rule.condition = alarm;
- rule.conditionId = alarm.id;
- rule.enabled = true;
- rule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-
- mPanel.handleUpdateManualRule(rule);
-
- assertProperConditionTagTypes(true);
- assertEquals(alarm, mPanel.getConditionTagAt(2).condition);
- assertTrue(mPanel.getConditionTagAt(2).rb.isChecked());
-
- assertEquals(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
- mPanel.getSelectedZen(Settings.Global.ZEN_MODE_OFF));
-
- rule.zenMode = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS;
-
- mPanel.handleUpdateManualRule(rule);
-
- assertProperConditionTagTypes(true);
- assertEquals(alarm, mPanel.getConditionTagAt(2).condition);
- assertTrue(mPanel.getConditionTagAt(2).rb.isChecked());
-
- assertEquals(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS,
- mPanel.getSelectedZen(Settings.Global.ZEN_MODE_OFF));
- }
-}
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 219facd..0502117 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -34,7 +34,7 @@
2731 power_soft_sleep_requested (savedwaketimems|2)
# Power save state has changed. See BatterySaverController.java for the details.
2739 battery_saver_mode (prevOffOrOn|1|5),(nowOffOrOn|1|5),(interactive|1|5),(features|3|5)
-27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|6),(total_duration|2|3),(total_battery_drain|1|6)
+27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|1),(delta_battery_drain_percent|1|6),(total_duration|2|3),(total_battery_drain|1|1),(total_battery_drain_percent|1|6)
#
# Leave IDs through 2740 for more power logs (2730 used by battery_discharge above)
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 1dd92f3..65e90bad 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -1397,23 +1397,6 @@
}
/**
- * Returns "true" if access to the specified location provider is allowed by the specified
- * user's settings. Access to all location providers is forbidden to non-location-provider
- * processes belonging to background users.
- *
- * @param provider the name of the location provider
- * @param uid the requestor's UID
- * @param userId the user id to query
- */
- private boolean isAllowedByUserSettingsLockedForUser(
- String provider, int uid, int userId) {
- if (!isCurrentProfile(UserHandle.getUserId(uid)) && !isUidALocationProvider(uid)) {
- return false;
- }
- return isLocationProviderEnabledForUser(provider, userId);
- }
-
- /**
* Returns the permission string associated with the specified resolution level.
*
* @param resolutionLevel the resolution level
@@ -2585,143 +2568,6 @@
}
/**
- * Method for enabling or disabling location.
- *
- * @param enabled true to enable location. false to disable location
- * @param userId the user id to set
- */
- @Override
- public void setLocationEnabledForUser(boolean enabled, int userId) {
- // Check INTERACT_ACROSS_USERS permission if userId is not current user id.
- checkInteractAcrossUsersPermission(userId);
-
- // Enable or disable all location providers. Fused provider and passive provider are
- // excluded.
- synchronized (mLock) {
- for(String provider : getAllProvidersForLocationSettings()) {
- setProviderEnabledForUser(provider, enabled, userId);
- }
- }
- }
-
- /**
- * Returns the current enabled/disabled status of location
- *
- * @param userId the user id to query
- * @return true if location is enabled. false if location is disabled.
- */
- @Override
- public boolean isLocationEnabledForUser(int userId) {
- // Check INTERACT_ACROSS_USERS permission if userId is not current user id.
- checkInteractAcrossUsersPermission(userId);
-
- // If at least one location provider is enabled, return true. Fused provider and passive
- // provider are excluded.
- synchronized (mLock) {
- for (String provider : getAllProvidersForLocationSettings()) {
- if (isProviderEnabledForUser(provider, userId)) {
- return true;
- }
- }
- return false;
- }
- }
-
- @Override
- public boolean isProviderEnabled(String provider) {
- return isProviderEnabledForUser(provider, UserHandle.getCallingUserId());
- }
-
- /**
- * Method for determining if a location provider is enabled.
- *
- * @param provider the location provider to query
- * @param userId the user id to query
- * @return true if the provider is enabled
- */
- @Override
- public boolean isProviderEnabledForUser(String provider, int userId) {
- // Check INTERACT_ACROSS_USERS permission if userId is not current user id.
- checkInteractAcrossUsersPermission(userId);
-
- // Fused provider is accessed indirectly via criteria rather than the provider-based APIs,
- // so we discourage its use
- if (LocationManager.FUSED_PROVIDER.equals(provider)) return false;
-
- int uid = Binder.getCallingUid();
- long identity = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- LocationProviderInterface p = mProvidersByName.get(provider);
- return p != null
- && isAllowedByUserSettingsLockedForUser(provider, uid, userId);
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- /**
- * Method for enabling or disabling a single location provider.
- *
- * @param provider the name of the provider
- * @param enabled true to enable the provider. false to disable the provider
- * @param userId the user id to set
- * @return true if the value was set successfully. false on failure.
- */
- @Override
- public boolean setProviderEnabledForUser(
- String provider, boolean enabled, int userId) {
- mContext.enforceCallingPermission(
- android.Manifest.permission.WRITE_SECURE_SETTINGS,
- "Requires WRITE_SECURE_SETTINGS permission");
-
- // Check INTERACT_ACROSS_USERS permission if userId is not current user id.
- checkInteractAcrossUsersPermission(userId);
-
- final long identity = Binder.clearCallingIdentity();
- try {
- synchronized (mLock) {
- // to ensure thread safety, we write the provider name with a '+' or '-'
- // and let the SettingsProvider handle it rather than reading and modifying
- // the list of enabled providers.
- if (enabled) {
- provider = "+" + provider;
- } else {
- provider = "-" + provider;
- }
- return Settings.Secure.putStringForUser(
- mContext.getContentResolver(),
- Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- provider,
- userId);
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
-
- /**
- * Return all location providers except fused provider and passive provider. These two
- * providers are not generating location by themselves, but only echo locations from other
- * providers.
- *
- * @return All location providers except fused provider and passive provider, including
- * providers that are not permitted to be accessed by the calling activity or are
- * currently disabled.
- */
- private List<String> getAllProvidersForLocationSettings() {
- List<String> providersForSettings = new ArrayList<>(mProviders.size());
- for (String provider : getAllProviders()) {
- if (provider.equals(LocationManager.PASSIVE_PROVIDER)) {
- continue;
- }
- providersForSettings.add(provider);
- }
- return providersForSettings;
- }
-
- /**
* Read location provider status from Settings.Secure
*
* @param provider the location provider to query
@@ -2742,23 +2588,6 @@
}
/**
- * Method for checking INTERACT_ACROSS_USERS permission if specified user id is not the same as
- * current user id
- *
- * @param userId the user id to get or set value
- */
- private void checkInteractAcrossUsersPermission(int userId) {
- int uid = Binder.getCallingUid();
- if (UserHandle.getUserId(uid) != userId) {
- if (ActivityManager.checkComponentPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS, uid, -1, true)
- != PERMISSION_GRANTED) {
- throw new SecurityException("Requires INTERACT_ACROSS_USERS permission");
- }
- }
- }
-
- /**
* Returns "true" if the UID belongs to a bound location provider.
*
* @param uid the uid
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5b8b691..f370393 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4027,9 +4027,13 @@
runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
- if ("true".equals(genDebugInfoProperty)) {
+ if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
}
+ String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
+ if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
+ runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
+ }
if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
}
@@ -4331,7 +4335,9 @@
final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED,
component.userId, component.realActivity.getPackageName(),
- component.realActivity.getShortClassName(), resumed ? 1 : 0);
+ component.realActivity.getShortClassName(), resumed ?
+ StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_FOREGROUND :
+ StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__ACTIVITY__MOVE_TO_BACKGROUND);
if (resumed) {
if (mUsageStatsService != null) {
mUsageStatsService.reportEvent(component.realActivity, component.userId,
@@ -12844,7 +12850,8 @@
}
// TODO: Where should the corresponding '1' (start) write go?
- StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED, 0);
+ StatsLog.write(StatsLog.DEVICE_ON_STATUS_CHANGED,
+ StatsLog.DEVICE_ON_STATUS_CHANGED__STATE__OFF);
boolean timedout = false;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 0d96468..ea52782 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -325,39 +325,38 @@
void noteProcessStart(String name, int uid) {
synchronized (mStats) {
mStats.noteProcessStartLocked(name, uid);
- // TODO: decide where this should be and use a constant instead of a literal.
- StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, 1);
+ StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
+ StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__EVENT__PROCESS_STARTED);
}
}
void noteProcessCrash(String name, int uid) {
synchronized (mStats) {
mStats.noteProcessCrashLocked(name, uid);
- // TODO: decide where this should be and use a constant instead of a literal.
- StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, 2);
+ StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
+ StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__EVENT__PROCESS_CRASHED);
}
}
void noteProcessAnr(String name, int uid) {
synchronized (mStats) {
mStats.noteProcessAnrLocked(name, uid);
- // TODO: decide where this should be and use a constant instead of a literal.
- StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, 3);
+ StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
+ StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__EVENT__PROCESS_ANRED);
}
}
void noteProcessFinish(String name, int uid) {
synchronized (mStats) {
mStats.noteProcessFinishLocked(name, uid);
- // TODO: decide where this should be and use a constant instead of a literal.
- StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, 0);
+ StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
+ StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__EVENT__PROCESS_FINISHED);
}
}
/** @param state Process state from ActivityManager.java. */
void noteUidProcessState(int uid, int state) {
synchronized (mStats) {
- // TODO: remove this once we figure out properly where and how
StatsLog.write(StatsLog.UID_PROCESS_STATE_CHANGED, uid,
ActivityManager.processStateAmToProto(state));
@@ -603,7 +602,6 @@
enforceCallingPermission();
if (DBG) Slog.d(TAG, "begin noteScreenState");
synchronized (mStats) {
- // TODO: remove this once we figure out properly where and how
StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, state);
mStats.noteScreenStateLocked(state);
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index e5762d2..21f9135 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -38,7 +38,6 @@
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
@@ -143,6 +142,14 @@
TelecomManager mTelecomManager;
/**
+ * Helper that is responsible for showing the right toast when a disallowed activity operation
+ * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
+ * fully locked mode we only show that unlocking is blocked.
+ */
+ @VisibleForTesting
+ LockTaskNotify mLockTaskNotify;
+
+ /**
* The chain of tasks in LockTask mode, in the order of when they first entered LockTask mode.
*
* The first task in the list, which started the current LockTask session, is called the root
@@ -468,7 +475,7 @@
getDevicePolicyManager().notifyLockTaskModeChanged(false, null, userId);
}
if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
- getStatusBarService().showPinningEnterExitToast(false /* entering */);
+ getLockTaskNotify().showPinningExitToast();
}
} catch (RemoteException ex) {
throw new RuntimeException(ex);
@@ -483,11 +490,7 @@
*/
void showLockTaskToast() {
if (mLockTaskModeState == LOCK_TASK_MODE_PINNED) {
- try {
- getStatusBarService().showPinningEscapeToast();
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to send pinning escape toast", e);
- }
+ mHandler.post(() -> getLockTaskNotify().showEscapeToast());
}
}
@@ -579,7 +582,7 @@
// When lock task starts, we disable the status bars.
try {
if (lockTaskModeState == LOCK_TASK_MODE_PINNED) {
- getStatusBarService().showPinningEnterExitToast(true /* entering */);
+ getLockTaskNotify().showPinningStartToast();
}
mLockTaskModeState = lockTaskModeState;
setStatusBarState(lockTaskModeState, userId);
@@ -832,6 +835,15 @@
return mTelecomManager;
}
+ // Should only be called on the handler thread
+ @NonNull
+ private LockTaskNotify getLockTaskNotify() {
+ if (mLockTaskNotify == null) {
+ mLockTaskNotify = new LockTaskNotify(mContext);
+ }
+ return mLockTaskNotify;
+ }
+
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "LockTaskController");
prefix = prefix + " ";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java b/services/core/java/com/android/server/am/LockTaskNotify.java
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java
rename to services/core/java/com/android/server/am/LockTaskNotify.java
index 0d07ad9..1dcb0ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenPinningNotify.java
+++ b/services/core/java/com/android/server/am/LockTaskNotify.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2013 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,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.phone;
+package com.android.server.am;
import android.content.Context;
import android.os.SystemClock;
@@ -22,37 +22,36 @@
import android.view.WindowManager;
import android.widget.Toast;
-import com.android.systemui.R;
-import com.android.systemui.SysUIToast;
+import com.android.internal.R;
/**
* Helper to manage showing/hiding a image to notify them that they are entering or exiting screen
* pinning mode. All exposed methods should be called from a handler thread.
*/
-public class ScreenPinningNotify {
- private static final String TAG = "ScreenPinningNotify";
+public class LockTaskNotify {
+ private static final String TAG = "LockTaskNotify";
private static final long SHOW_TOAST_MINIMUM_INTERVAL = 1000;
private final Context mContext;
private Toast mLastToast;
private long mLastShowToastTime;
- public ScreenPinningNotify(Context context) {
+ public LockTaskNotify(Context context) {
mContext = context;
}
/** Show "Screen pinned" toast. */
void showPinningStartToast() {
- makeAllUserToastAndShow(R.string.screen_pinning_start);
+ makeAllUserToastAndShow(R.string.lock_to_app_start);
}
/** Show "Screen unpinned" toast. */
void showPinningExitToast() {
- makeAllUserToastAndShow(R.string.screen_pinning_exit);
+ makeAllUserToastAndShow(R.string.lock_to_app_exit);
}
/** Show a toast that describes the gesture the user should use to escape pinned mode. */
- void showEscapeToast(boolean isRecentsButtonVisible) {
+ void showEscapeToast() {
long showToastTime = SystemClock.elapsedRealtime();
if ((showToastTime - mLastShowToastTime) < SHOW_TOAST_MINIMUM_INTERVAL) {
Slog.i(TAG, "Ignore toast since it is requested in very short interval.");
@@ -61,14 +60,14 @@
if (mLastToast != null) {
mLastToast.cancel();
}
- mLastToast = makeAllUserToastAndShow(isRecentsButtonVisible
- ? R.string.screen_pinning_toast
- : R.string.screen_pinning_toast_recents_invisible);
+ mLastToast = makeAllUserToastAndShow(R.string.lock_to_app_toast);
mLastShowToastTime = showToastTime;
}
private Toast makeAllUserToastAndShow(int resId) {
- Toast toast = SysUIToast.makeText(mContext, resId, Toast.LENGTH_LONG);
+ Toast toast = Toast.makeText(mContext, resId, Toast.LENGTH_LONG);
+ toast.getWindowParams().privateFlags |=
+ WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
toast.show();
return toast;
}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index e0baeee..401c05e 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -862,7 +862,8 @@
}
startTrackingJobLocked(jobStatus, toCancel);
StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED,
- uId, null, jobStatus.getBatteryName(), 2);
+ uId, null, jobStatus.getBatteryName(),
+ StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED);
// If the job is immediately ready to run, then we can just immediately
// put it in the pending list and try to schedule it. This is especially
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index c02331d..5060c4d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -693,7 +693,7 @@
InputStream fileIn = new GZIPInputStream(new FileInputStream(srcFile));
OutputStream fileOut = new FileOutputStream(dstFile, false /*append*/);
) {
- Streams.copy(fileIn, fileOut);
+ FileUtils.copy(fileIn, fileOut);
Os.chmod(dstFile.getAbsolutePath(), 0644);
return PackageManager.INSTALL_SUCCEEDED;
} catch (IOException e) {
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySavingStats.java b/services/core/java/com/android/server/power/batterysaver/BatterySavingStats.java
index 9466350..b0b07ea 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySavingStats.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySavingStats.java
@@ -32,6 +32,8 @@
/**
* This class keeps track of battery drain rate.
*
+ * TODO: The use of the terms "percent" and "level" in this class is not standard. Fix it.
+ *
* Test:
atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java
*/
@@ -96,8 +98,12 @@
public int startBatteryLevel;
public int endBatteryLevel;
+ public int startBatteryPercent;
+ public int endBatteryPercent;
+
public long totalTimeMillis;
public int totalBatteryDrain;
+ public int totalBatteryDrainPercent;
public long totalMinutes() {
return totalTimeMillis / 60_000;
@@ -110,14 +116,26 @@
return (double) totalBatteryDrain / (totalTimeMillis / (60.0 * 60 * 1000));
}
+ public double drainPercentPerHour() {
+ if (totalTimeMillis == 0) {
+ return 0;
+ }
+ return (double) totalBatteryDrainPercent / (totalTimeMillis / (60.0 * 60 * 1000));
+ }
+
@VisibleForTesting
String toStringForTest() {
return "{" + totalMinutes() + "m," + totalBatteryDrain + ","
- + String.format("%.2f", drainPerHour()) + "}";
+ + String.format("%.2f", drainPerHour()) + "uA/H,"
+ + String.format("%.2f", drainPercentPerHour()) + "%"
+ + "}";
}
}
@VisibleForTesting
+ static final String COUNTER_POWER_PERCENT_PREFIX = "battery_saver_stats_percent_";
+
+ @VisibleForTesting
static final String COUNTER_POWER_MILLIAMPS_PREFIX = "battery_saver_stats_milliamps_";
@VisibleForTesting
@@ -166,6 +184,9 @@
private BatteryManagerInternal getBatteryManagerInternal() {
if (mBatteryManagerInternal == null) {
mBatteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class);
+ if (mBatteryManagerInternal == null) {
+ Slog.wtf(TAG, "BatteryManagerInternal not initialized");
+ }
}
return mBatteryManagerInternal;
}
@@ -229,12 +250,20 @@
int injectBatteryLevel() {
final BatteryManagerInternal bmi = getBatteryManagerInternal();
if (bmi == null) {
- Slog.wtf(TAG, "BatteryManagerInternal not initialized");
return 0;
}
return bmi.getBatteryChargeCounter();
}
+ @VisibleForTesting
+ int injectBatteryPercent() {
+ final BatteryManagerInternal bmi = getBatteryManagerInternal();
+ if (bmi == null) {
+ return 0;
+ }
+ return bmi.getBatteryLevel();
+ }
+
/**
* Called from the outside whenever any of the states changes, when the device is not plugged
* in.
@@ -262,33 +291,39 @@
}
final long now = injectCurrentTime();
final int batteryLevel = injectBatteryLevel();
+ final int batteryPercent = injectBatteryPercent();
- endLastStateLocked(now, batteryLevel);
- startNewStateLocked(newState, now, batteryLevel);
- mMetricsLoggerHelper.transitionState(newState, now, batteryLevel);
+ endLastStateLocked(now, batteryLevel, batteryPercent);
+ startNewStateLocked(newState, now, batteryLevel, batteryPercent);
+ mMetricsLoggerHelper.transitionState(newState, now, batteryLevel, batteryPercent);
}
- private void endLastStateLocked(long now, int batteryLevel) {
+ private void endLastStateLocked(long now, int batteryLevel, int batteryPercent) {
if (mCurrentState < 0) {
return;
}
final Stat stat = getStat(mCurrentState);
stat.endBatteryLevel = batteryLevel;
+ stat.endBatteryPercent = batteryPercent;
stat.endTime = now;
final long deltaTime = stat.endTime - stat.startTime;
final int deltaDrain = stat.startBatteryLevel - stat.endBatteryLevel;
+ final int deltaPercent = stat.startBatteryPercent - stat.endBatteryPercent;
stat.totalTimeMillis += deltaTime;
stat.totalBatteryDrain += deltaDrain;
+ stat.totalBatteryDrainPercent += deltaPercent;
if (DEBUG) {
Slog.d(TAG, "State summary: " + stateToString(mCurrentState)
+ ": " + (deltaTime / 1_000) + "s "
+ "Start level: " + stat.startBatteryLevel + "uA "
+ "End level: " + stat.endBatteryLevel + "uA "
- + deltaDrain + "uA");
+ + "Start percent: " + stat.startBatteryPercent + "% "
+ + "End percent: " + stat.endBatteryPercent + "% "
+ + "Drain " + deltaDrain + "uA");
}
EventLogTags.writeBatterySavingStats(
BatterySaverState.fromIndex(mCurrentState),
@@ -296,12 +331,14 @@
DozeState.fromIndex(mCurrentState),
deltaTime,
deltaDrain,
+ deltaPercent,
stat.totalTimeMillis,
- stat.totalBatteryDrain);
+ stat.totalBatteryDrain,
+ stat.totalBatteryDrainPercent);
}
- private void startNewStateLocked(int newState, long now, int batteryLevel) {
+ private void startNewStateLocked(int newState, long now, int batteryLevel, int batteryPercent) {
if (DEBUG) {
Slog.d(TAG, "New state: " + stateToString(newState));
}
@@ -313,6 +350,7 @@
final Stat stat = getStat(mCurrentState);
stat.startBatteryLevel = batteryLevel;
+ stat.startBatteryPercent = batteryPercent;
stat.startTime = now;
stat.endTime = 0;
}
@@ -325,7 +363,7 @@
indent = indent + " ";
pw.print(indent);
- pw.println("Battery Saver: Off On");
+ pw.println("Battery Saver: Off On");
dumpLineLocked(pw, indent, InteractiveState.NON_INTERACTIVE, "NonIntr",
DozeState.NOT_DOZING, "NonDoze");
dumpLineLocked(pw, indent, InteractiveState.INTERACTIVE, " Intr",
@@ -357,12 +395,14 @@
final Stat offStat = getStat(BatterySaverState.OFF, interactiveState, dozeState);
final Stat onStat = getStat(BatterySaverState.ON, interactiveState, dozeState);
- pw.println(String.format("%6dm %6dmA %8.1fmA/h %6dm %6dmA %8.1fmA/h",
+ pw.println(String.format("%6dm %6dmA (%3d%%) %8.1fmA/h %6dm %6dmA (%3d%%) %8.1fmA/h",
offStat.totalMinutes(),
offStat.totalBatteryDrain / 1000,
+ offStat.totalBatteryDrainPercent,
offStat.drainPerHour() / 1000.0,
onStat.totalMinutes(),
onStat.totalBatteryDrain / 1000,
+ onStat.totalBatteryDrainPercent,
onStat.drainPerHour() / 1000.0));
}
@@ -371,12 +411,13 @@
private int mLastState = STATE_NOT_INITIALIZED;
private long mStartTime;
private int mStartBatteryLevel;
+ private int mStartPercent;
private static final int STATE_CHANGE_DETECT_MASK =
(BatterySaverState.MASK << BatterySaverState.SHIFT) |
(InteractiveState.MASK << InteractiveState.SHIFT);
- public void transitionState(int newState, long now, int batteryLevel) {
+ public void transitionState(int newState, long now, int batteryLevel, int batteryPercent) {
final boolean stateChanging =
((mLastState >= 0) ^ (newState >= 0)) ||
(((mLastState ^ newState) & STATE_CHANGE_DETECT_MASK) != 0);
@@ -384,11 +425,13 @@
if (mLastState >= 0) {
final long deltaTime = now - mStartTime;
final int deltaBattery = mStartBatteryLevel - batteryLevel;
+ final int deltaPercent = mStartPercent - batteryPercent;
- report(mLastState, deltaTime, deltaBattery);
+ report(mLastState, deltaTime, deltaBattery, deltaPercent);
}
mStartTime = now;
mStartBatteryLevel = batteryLevel;
+ mStartPercent = batteryPercent;
}
mLastState = newState;
}
@@ -405,9 +448,10 @@
}
}
- void report(int state, long deltaTimeMs, int deltaBatteryUa) {
+ void report(int state, long deltaTimeMs, int deltaBatteryUa, int deltaPercent) {
final String suffix = getCounterSuffix(state);
mMetricsLogger.count(COUNTER_POWER_MILLIAMPS_PREFIX + suffix, deltaBatteryUa / 1000);
+ mMetricsLogger.count(COUNTER_POWER_PERCENT_PREFIX + suffix, deltaPercent);
mMetricsLogger.count(COUNTER_TIME_SECONDS_PREFIX + suffix, (int) (deltaTimeMs / 1000));
}
}
diff --git a/services/core/java/com/android/server/slice/SliceFullAccessList.java b/services/core/java/com/android/server/slice/SliceFullAccessList.java
index 591e809..5e0cd03 100644
--- a/services/core/java/com/android/server/slice/SliceFullAccessList.java
+++ b/services/core/java/com/android/server/slice/SliceFullAccessList.java
@@ -63,6 +63,15 @@
pkgs.add(pkg);
}
+ public void removeGrant(String pkg, int userId) {
+ ArraySet<String> pkgs = mFullAccessPkgs.get(userId, null);
+ if (pkgs == null) {
+ pkgs = new ArraySet<>();
+ mFullAccessPkgs.put(userId, pkgs);
+ }
+ pkgs.remove(pkg);
+ }
+
public void writeXml(XmlSerializer out) throws IOException {
out.startTag(null, TAG_LIST);
out.attribute(null, ATT_VERSION, String.valueOf(DB_VERSION));
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index 5db0fc0..c4871df 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -31,9 +31,11 @@
import android.app.slice.ISliceManager;
import android.app.slice.SliceManager;
import android.app.slice.SliceSpec;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
@@ -92,6 +94,7 @@
private final Handler mHandler;
private final ContentObserver mObserver;
private final AtomicFile mSliceAccessFile;
+ @GuardedBy("mAccessList")
private final SliceFullAccessList mAccessList;
public SliceManagerService(Context context) {
@@ -127,11 +130,19 @@
InputStream input = mSliceAccessFile.openRead();
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setInput(input, Encoding.UTF_8.name());
- mAccessList.readXml(parser);
+ synchronized (mAccessList) {
+ mAccessList.readXml(parser);
+ }
} catch (IOException | XmlPullParserException e) {
Slog.d(TAG, "Can't read slice access file", e);
}
}
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addDataScheme("package");
+ mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
}
/// ----- Lifecycle stuff -----
@@ -223,7 +234,9 @@
getContext().enforceCallingOrSelfPermission(permission.MANAGE_SLICE_PERMISSIONS,
"Slice granting requires MANAGE_SLICE_PERMISSIONS");
if (allSlices) {
- mAccessList.grantFullAccess(pkg, Binder.getCallingUserHandle().getIdentifier());
+ synchronized (mAccessList) {
+ mAccessList.grantFullAccess(pkg, Binder.getCallingUserHandle().getIdentifier());
+ }
mHandler.post(mSaveAccessList);
} else {
synchronized (mLock) {
@@ -245,6 +258,13 @@
}
/// ----- internal code -----
+ private void removeFullAccess(String pkg, int userId) {
+ synchronized (mAccessList) {
+ mAccessList.removeGrant(pkg, userId);
+ }
+ mHandler.post(mSaveAccessList);
+ }
+
protected void removePinnedSlice(Uri uri) {
synchronized (mLock) {
mPinnedSlicesByUri.remove(uri).destroy();
@@ -444,7 +464,9 @@
}
private boolean isGrantedFullAccess(String pkg, int userId) {
- return mAccessList.hasFullAccess(pkg, userId);
+ synchronized (mAccessList) {
+ return mAccessList.hasFullAccess(pkg, userId);
+ }
}
private static ServiceThread createHandler() {
@@ -469,7 +491,9 @@
try {
XmlSerializer out = XmlPullParserFactory.newInstance().newSerializer();
out.setOutput(stream, Encoding.UTF_8.name());
- mAccessList.writeXml(out);
+ synchronized (mAccessList) {
+ mAccessList.writeXml(out);
+ }
out.flush();
mSliceAccessFile.finishWrite(stream);
} catch (IOException | XmlPullParserException e) {
@@ -480,6 +504,35 @@
}
};
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ if (userId == UserHandle.USER_NULL) {
+ Slog.w(TAG, "Intent broadcast does not contain user handle: " + intent);
+ return;
+ }
+ Uri data = intent.getData();
+ String pkg = data != null ? data.getSchemeSpecificPart() : null;
+ if (pkg == null) {
+ Slog.w(TAG, "Intent broadcast does not contain package name: " + intent);
+ return;
+ }
+ switch (intent.getAction()) {
+ case Intent.ACTION_PACKAGE_REMOVED:
+ final boolean replacing =
+ intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+ if (!replacing) {
+ removeFullAccess(pkg, userId);
+ }
+ break;
+ case Intent.ACTION_PACKAGE_DATA_CLEARED:
+ removeFullAccess(pkg, userId);
+ break;
+ }
+ }
+ };
+
public static class Lifecycle extends SystemService {
private SliceManagerService mService;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 7c170ae..adb368b 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -56,6 +56,7 @@
import java.util.ArrayList;
import java.util.List;
+
/**
* A note on locking: We rely on the fact that calls onto mBar are oneway or
* if they are local, that they just enqueue messages to not deadlock.
@@ -524,26 +525,6 @@
}
@Override
- public void showPinningEnterExitToast(boolean entering) throws RemoteException {
- if (mBar != null) {
- try {
- mBar.showPinningEnterExitToast(entering);
- } catch (RemoteException ex) {
- }
- }
- }
-
- @Override
- public void showPinningEscapeToast() throws RemoteException {
- if (mBar != null) {
- try {
- mBar.showPinningEscapeToast();
- } catch (RemoteException ex) {
- }
- }
- }
-
- @Override
public void showFingerprintDialog(Bundle bundle, IFingerprintDialogReceiver receiver) {
if (mBar != null) {
try {
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index 3f32079..b00e595 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -72,20 +72,23 @@
}
/** Cancels the notification */
- void cancel() {
+ void cancel(boolean deleteChannel) {
// We can't call into NotificationManager with WM lock held since it might call into AM.
// So, we post a message to do it later.
- mService.mH.post(this::onCancelNotification);
+ mService.mH.post(() -> onCancelNotification(deleteChannel));
}
/** Don't call with the window manager lock held! */
- private void onCancelNotification() {
+ private void onCancelNotification(boolean deleteChannel) {
if (!mPosted) {
// Notification isn't currently posted...
return;
}
mPosted = false;
mNotificationManager.cancel(mNotificationTag, NOTIFICATION_ID);
+ if (deleteChannel) {
+ mNotificationManager.deleteNotificationChannel(mNotificationTag);
+ }
}
/** Don't call with the window manager lock held! */
@@ -146,8 +149,12 @@
final String nameChannel =
context.getString(R.string.alert_windows_notification_channel_name, appName);
- final NotificationChannel channel =
- new NotificationChannel(mNotificationTag, nameChannel, IMPORTANCE_MIN);
+
+ NotificationChannel channel = mNotificationManager.getNotificationChannel(mNotificationTag);
+ if (channel != null) {
+ return;
+ }
+ channel = new NotificationChannel(mNotificationTag, nameChannel, IMPORTANCE_MIN);
channel.enableLights(false);
channel.enableVibration(false);
channel.setBlockableSystem(true);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7674b5e..2512dbd 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -662,7 +662,7 @@
mWallpaperController.updateWallpaperVisibility();
}
- w.handleWindowMovedIfNeeded(mPendingTransaction);
+ w.handleWindowMovedIfNeeded();
final WindowStateAnimator winAnimator = w.mWinAnimator;
@@ -1542,11 +1542,11 @@
* Callback used to trigger bounds update after configuration change and get ids of stacks whose
* bounds were updated.
*/
- void updateStackBoundsAfterConfigChange(@NonNull List<Integer> changedStackList) {
+ void updateStackBoundsAfterConfigChange(@NonNull List<TaskStack> changedStackList) {
for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
final TaskStack stack = mTaskStackContainers.getChildAt(i);
if (stack.updateBoundsAfterConfigChange()) {
- changedStackList.add(stack.mStackId);
+ changedStackList.add(stack);
}
}
@@ -3599,8 +3599,6 @@
}
private final class AboveAppWindowContainers extends NonAppWindowContainers {
- private final Dimmer mDimmer = new Dimmer(this);
- private final Rect mTmpDimBoundsRect = new Rect();
AboveAppWindowContainers(String name, WindowManagerService service) {
super(name, service);
}
@@ -3632,22 +3630,6 @@
imeContainer.assignRelativeLayer(t, getSurfaceControl(), Integer.MAX_VALUE);
}
}
-
- @Override
- Dimmer getDimmer() {
- return mDimmer;
- }
-
- @Override
- void prepareSurfaces() {
- mDimmer.resetDimStates();
- super.prepareSurfaces();
- getBounds(mTmpDimBoundsRect);
-
- if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
- scheduleAnimation();
- }
- }
}
/**
@@ -3679,6 +3661,9 @@
};
private final String mName;
+ private final Dimmer mDimmer = new Dimmer(this);
+ private final Rect mTmpDimBoundsRect = new Rect();
+
NonAppWindowContainers(String name, WindowManagerService service) {
super(service);
mName = name;
@@ -3722,6 +3707,22 @@
String getName() {
return mName;
}
+
+ @Override
+ Dimmer getDimmer() {
+ return mDimmer;
+ }
+
+ @Override
+ void prepareSurfaces() {
+ mDimmer.resetDimStates();
+ super.prepareSurfaces();
+ getBounds(mTmpDimBoundsRect);
+
+ if (mDimmer.updateDims(getPendingTransaction(), mTmpDimBoundsRect)) {
+ scheduleAnimation();
+ }
+ }
}
private class NonMagnifiableWindowContainers extends NonAppWindowContainers {
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 9251993..5bc739e 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -96,13 +96,17 @@
// Scale the timeout with the animator scale the controlling app is using.
mHandler.postDelayed(mTimeoutRunnable,
(long) (TIMEOUT_MS * mService.getCurrentAnimatorScale()));
- try {
- mRemoteAnimationAdapter.getRunner().onAnimationStart(createAnimations(),
- mFinishedCallback);
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to start remote animation", e);
- onAnimationFinished();
- }
+
+ final RemoteAnimationTarget[] animations = createAnimations();
+ mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
+ try {
+ mRemoteAnimationAdapter.getRunner().onAnimationStart(animations,
+ mFinishedCallback);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to start remote animation", e);
+ onAnimationFinished();
+ }
+ });
}
private RemoteAnimationTarget[] createAnimations() {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 68c8995..8d1a822 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -47,6 +47,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import java.util.function.Consumer;
import static android.app.AppOpsManager.MODE_ALLOWED;
@@ -126,7 +127,8 @@
boolean mOrientationChangeComplete = true;
boolean mWallpaperActionPending = false;
- private final ArrayList<Integer> mChangedStackList = new ArrayList();
+ private final ArrayList<TaskStack> mTmpStackList = new ArrayList();
+ private final ArrayList<Integer> mTmpStackIds = new ArrayList<>();
// State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
// instances will be replaced with an instance that writes a binary representation of all
@@ -333,7 +335,8 @@
/**
* Set new display override config and return array of ids of stacks that were changed during
- * update. If called for the default display, global configuration will also be updated.
+ * update. If called for the default display, global configuration will also be updated. Stacks
+ * that are marked for deferred removal are excluded from the returned array.
*/
int[] setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId) {
final DisplayContent displayContent = getDisplayContent(displayId);
@@ -346,24 +349,42 @@
if (!configChanged) {
return null;
}
+
displayContent.onOverrideConfigurationChanged(newConfiguration);
+ mTmpStackList.clear();
if (displayId == DEFAULT_DISPLAY) {
// Override configuration of the default display duplicates global config. In this case
// we also want to update the global config.
- return setGlobalConfigurationIfNeeded(newConfiguration);
+ setGlobalConfigurationIfNeeded(newConfiguration, mTmpStackList);
} else {
- return updateStackBoundsAfterConfigChange(displayId);
+ updateStackBoundsAfterConfigChange(displayId, mTmpStackList);
}
+
+ mTmpStackIds.clear();
+ final int stackCount = mTmpStackList.size();
+
+ for (int i = 0; i < stackCount; ++i) {
+ final TaskStack stack = mTmpStackList.get(i);
+
+ // We only include stacks that are not marked for removal as they do not exist outside
+ // of WindowManager at this point.
+ if (!stack.mDeferRemoval) {
+ mTmpStackIds.add(stack.mStackId);
+ }
+ }
+
+ return mTmpStackIds.isEmpty() ? null : ArrayUtils.convertToIntArray(mTmpStackIds);
}
- private int[] setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
+ private void setGlobalConfigurationIfNeeded(Configuration newConfiguration,
+ List<TaskStack> changedStacks) {
final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
if (!configChanged) {
- return null;
+ return;
}
onConfigurationChanged(newConfiguration);
- return updateStackBoundsAfterConfigChange();
+ updateStackBoundsAfterConfigChange(changedStacks);
}
@Override
@@ -378,26 +399,18 @@
* Callback used to trigger bounds update after configuration change and get ids of stacks whose
* bounds were updated.
*/
- private int[] updateStackBoundsAfterConfigChange() {
- mChangedStackList.clear();
-
+ private void updateStackBoundsAfterConfigChange(List<TaskStack> changedStacks) {
final int numDisplays = mChildren.size();
for (int i = 0; i < numDisplays; ++i) {
final DisplayContent dc = mChildren.get(i);
- dc.updateStackBoundsAfterConfigChange(mChangedStackList);
+ dc.updateStackBoundsAfterConfigChange(changedStacks);
}
-
- return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
}
/** Same as {@link #updateStackBoundsAfterConfigChange()} but only for a specific display. */
- private int[] updateStackBoundsAfterConfigChange(int displayId) {
- mChangedStackList.clear();
-
+ private void updateStackBoundsAfterConfigChange(int displayId, List<TaskStack> changedStacks) {
final DisplayContent dc = getDisplayContent(displayId);
- dc.updateStackBoundsAfterConfigChange(mChangedStackList);
-
- return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
+ dc.updateStackBoundsAfterConfigChange(changedStacks);
}
private void prepareFreezingTaskBounds() {
@@ -599,6 +612,8 @@
"<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
}
+ mService.mAnimator.executeAfterPrepareSurfacesRunnables();
+
final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
// If we are ready to perform an app transition, check through all of the app tokens to be
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 04ae38e..f09a294 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -547,7 +547,7 @@
if (allowed) {
mAlertWindowNotification.post();
} else {
- mAlertWindowNotification.cancel();
+ mAlertWindowNotification.cancel(false /* deleteChannel */);
}
}
}
@@ -586,7 +586,7 @@
if (mAlertWindowNotification == null) {
return;
}
- mAlertWindowNotification.cancel();
+ mAlertWindowNotification.cancel(true /* deleteChannel */);
mAlertWindowNotification = null;
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index cec13ab..b0d42f2 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -92,6 +92,7 @@
* executed and the corresponding transaction is closed and applied.
*/
private final ArrayList<Runnable> mAfterPrepareSurfacesRunnables = new ArrayList<>();
+ private boolean mInExecuteAfterPrepareSurfacesRunnables;
WindowAnimator(final WindowManagerService service) {
mService = service;
@@ -438,7 +439,13 @@
scheduleAnimation();
}
- private void executeAfterPrepareSurfacesRunnables() {
+ void executeAfterPrepareSurfacesRunnables() {
+
+ // Don't even think about to start recursing!
+ if (mInExecuteAfterPrepareSurfacesRunnables) {
+ return;
+ }
+ mInExecuteAfterPrepareSurfacesRunnables = true;
// Traverse in order they were added.
final int size = mAfterPrepareSurfacesRunnables.size();
@@ -446,5 +453,6 @@
mAfterPrepareSurfacesRunnables.get(i).run();
}
mAfterPrepareSurfacesRunnables.clear();
+ mInExecuteAfterPrepareSurfacesRunnables = false;
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 066e4e6..d565a6a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -24,8 +24,6 @@
import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.StatusBarManager.DISABLE_MASK;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.EXTRA_USER_HANDLE;
@@ -125,7 +123,6 @@
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.IAssistDataReceiver;
-import android.app.WindowConfiguration;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -2466,6 +2463,7 @@
mWaitingForConfig = false;
mLastFinishedFreezeSource = "new-config";
}
+
return mRoot.setDisplayOverrideConfigurationIfNeeded(overrideConfig, displayId);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 36e3612..a9f2e03 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1758,7 +1758,7 @@
* listeners and optionally animate it. Simply checking a change of position is not enough,
* because being move due to dock divider is not a trigger for animation.
*/
- void handleWindowMovedIfNeeded(Transaction t) {
+ void handleWindowMovedIfNeeded() {
if (!hasMoved()) {
return;
}
@@ -1776,7 +1776,7 @@
&& !isDragResizing() && !adjustedForMinimizedDockOrIme
&& getWindowConfiguration().hasMovementAnimations()
&& !mWinAnimator.mLastHidden) {
- startMoveAnimation(t, left, top);
+ startMoveAnimation(left, top);
}
//TODO (multidisplay): Accessibility supported only for the default display.
@@ -4360,7 +4360,7 @@
commitPendingTransaction();
}
- private void startMoveAnimation(Transaction t, int left, int top) {
+ private void startMoveAnimation(int left, int top) {
if (DEBUG_ANIM) Slog.v(TAG, "Setting move animation on " + this);
final Point oldPosition = new Point();
final Point newPosition = new Point();
@@ -4369,7 +4369,7 @@
final AnimationAdapter adapter = new LocalAnimationAdapter(
new MoveAnimationSpec(oldPosition.x, oldPosition.y, newPosition.x, newPosition.y),
mService.mSurfaceAnimationRunner);
- startAnimation(t, adapter);
+ startAnimation(getPendingTransaction(), adapter);
}
private void startAnimation(Transaction t, AnimationAdapter adapter) {
diff --git a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
index 1cbb399..d2ae22b 100644
--- a/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/LockTaskControllerTest.java
@@ -90,6 +90,7 @@
@Mock private IStatusBarService mStatusBarService;
@Mock private WindowManagerService mWindowManager;
@Mock private LockPatternUtils mLockPatternUtils;
+ @Mock private LockTaskNotify mLockTaskNotify;
@Mock private StatusBarManagerInternal mStatusBarManagerInternal;
@Mock private TelecomManager mTelecomManager;
@Mock private RecentTasks mRecentTasks;
@@ -122,6 +123,7 @@
mLockTaskController.mDevicePolicyManager = mDevicePolicyManager;
mLockTaskController.mTelecomManager = mTelecomManager;
mLockTaskController.mLockPatternUtils = mLockPatternUtils;
+ mLockTaskController.mLockTaskNotify = mLockTaskNotify;
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
LocalServices.addService(StatusBarManagerInternal.class, mStatusBarManagerInternal);
@@ -206,7 +208,7 @@
// THEN lock task mode should be started
verifyLockTaskStarted(STATUS_BAR_MASK_PINNED, DISABLE2_NONE);
// THEN screen pinning toast should be shown
- verify(mStatusBarService).showPinningEnterExitToast(true /* entering */);
+ verify(mLockTaskNotify).showPinningStartToast();
}
@Test
@@ -375,7 +377,7 @@
// THEN the keyguard should be shown
verify(mLockPatternUtils).requireCredentialEntry(UserHandle.USER_ALL);
// THEN screen pinning toast should be shown
- verify(mStatusBarService).showPinningEnterExitToast(false /* entering */);
+ verify(mLockTaskNotify).showPinningExitToast();
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java
index c3714c8..f7516b2 100644
--- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySavingStatsTest.java
@@ -63,6 +63,11 @@
return mBatteryLevel;
}
+ @Override
+ int injectBatteryPercent() {
+ return mBatteryLevel / 10;
+ }
+
void assertDumpable() {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
dump(new PrintWriter(out), ""); // Just make sure it won't crash.
@@ -102,7 +107,7 @@
target.assertDumpable();
target.advanceClock(1);
- target.drainBattery(2);
+ target.drainBattery(200);
target.transitionState(
BatterySaverState.OFF,
@@ -110,7 +115,7 @@
DozeState.NOT_DOZING);
target.advanceClock(4);
- target.drainBattery(1);
+ target.drainBattery(100);
target.transitionState(
BatterySaverState.OFF,
@@ -118,7 +123,7 @@
DozeState.NOT_DOZING);
target.advanceClock(2);
- target.drainBattery(5);
+ target.drainBattery(500);
target.transitionState(
BatterySaverState.OFF,
@@ -126,7 +131,7 @@
DozeState.NOT_DOZING);
target.advanceClock(4);
- target.drainBattery(1);
+ target.drainBattery(100);
target.transitionState(
BatterySaverState.OFF,
@@ -134,7 +139,7 @@
DozeState.NOT_DOZING);
target.advanceClock(2);
- target.drainBattery(5);
+ target.drainBattery(500);
target.transitionState(
BatterySaverState.OFF,
@@ -142,7 +147,7 @@
DozeState.NOT_DOZING);
target.advanceClock(3);
- target.drainBattery(1);
+ target.drainBattery(100);
target.transitionState(
BatterySaverState.OFF,
@@ -150,7 +155,7 @@
DozeState.LIGHT);
target.advanceClock(5);
- target.drainBattery(1);
+ target.drainBattery(100);
target.transitionState(
BatterySaverState.OFF,
@@ -158,7 +163,7 @@
DozeState.DEEP);
target.advanceClock(1);
- target.drainBattery(2);
+ target.drainBattery(200);
target.transitionState(
BatterySaverState.ON,
@@ -166,7 +171,7 @@
DozeState.NOT_DOZING);
target.advanceClock(1);
- target.drainBattery(3);
+ target.drainBattery(300);
target.transitionState(
BatterySaverState.OFF,
@@ -174,7 +179,7 @@
DozeState.NOT_DOZING);
target.advanceClock(3);
- target.drainBattery(5);
+ target.drainBattery(500);
target.transitionState(
BatterySaverState.ON,
@@ -182,12 +187,12 @@
DozeState.NOT_DOZING);
target.advanceClock(3);
- target.drainBattery(5);
+ target.drainBattery(500);
target.startCharging();
target.advanceClock(5);
- target.drainBattery(10);
+ target.drainBattery(1000);
target.transitionState(
BatterySaverState.ON,
@@ -195,25 +200,25 @@
DozeState.NOT_DOZING);
target.advanceClock(5);
- target.drainBattery(1);
+ target.drainBattery(100);
target.startCharging();
target.assertDumpable();
assertEquals(
- "BS=0,I=0,D=0:{4m,10,150.00}\n" +
- "BS=1,I=0,D=0:{0m,0,0.00}\n" +
- "BS=0,I=1,D=0:{14m,8,34.29}\n" +
- "BS=1,I=1,D=0:{9m,9,60.00}\n" +
- "BS=0,I=0,D=1:{5m,1,12.00}\n" +
- "BS=1,I=0,D=1:{0m,0,0.00}\n" +
- "BS=0,I=1,D=1:{0m,0,0.00}\n" +
- "BS=1,I=1,D=1:{0m,0,0.00}\n" +
- "BS=0,I=0,D=2:{1m,2,120.00}\n" +
- "BS=1,I=0,D=2:{0m,0,0.00}\n" +
- "BS=0,I=1,D=2:{0m,0,0.00}\n" +
- "BS=1,I=1,D=2:{0m,0,0.00}",
+ "BS=0,I=0,D=0:{4m,1000,15000.00uA/H,1500.00%}\n" +
+ "BS=1,I=0,D=0:{0m,0,0.00uA/H,0.00%}\n" +
+ "BS=0,I=1,D=0:{14m,800,3428.57uA/H,342.86%}\n" +
+ "BS=1,I=1,D=0:{9m,900,6000.00uA/H,600.00%}\n" +
+ "BS=0,I=0,D=1:{5m,100,1200.00uA/H,120.00%}\n" +
+ "BS=1,I=0,D=1:{0m,0,0.00uA/H,0.00%}\n" +
+ "BS=0,I=1,D=1:{0m,0,0.00uA/H,0.00%}\n" +
+ "BS=1,I=1,D=1:{0m,0,0.00uA/H,0.00%}\n" +
+ "BS=0,I=0,D=2:{1m,200,12000.00uA/H,1200.00%}\n" +
+ "BS=1,I=0,D=2:{0m,0,0.00uA/H,0.00%}\n" +
+ "BS=0,I=1,D=2:{0m,0,0.00uA/H,0.00%}\n" +
+ "BS=1,I=1,D=2:{0m,0,0.00uA/H,0.00%}",
target.toDebugString());
}
@@ -245,6 +250,7 @@
DozeState.NOT_DOZING);
assertMetricsLog(BatterySavingStats.COUNTER_POWER_MILLIAMPS_PREFIX + "01", 2);
+ assertMetricsLog(BatterySavingStats.COUNTER_POWER_PERCENT_PREFIX + "01", 200);
assertMetricsLog(BatterySavingStats.COUNTER_TIME_SECONDS_PREFIX + "01", 60);
target.advanceClock(1);
@@ -277,15 +283,17 @@
DozeState.NOT_DOZING);
assertMetricsLog(BatterySavingStats.COUNTER_POWER_MILLIAMPS_PREFIX + "00", 2 * 3);
+ assertMetricsLog(BatterySavingStats.COUNTER_POWER_PERCENT_PREFIX + "00", 200 * 3);
assertMetricsLog(BatterySavingStats.COUNTER_TIME_SECONDS_PREFIX + "00", 60 * 3);
target.advanceClock(10);
- target.drainBattery(10_000);
+ target.drainBattery(10000);
reset(mMetricsLogger);
target.startCharging();
assertMetricsLog(BatterySavingStats.COUNTER_POWER_MILLIAMPS_PREFIX + "11", 10);
+ assertMetricsLog(BatterySavingStats.COUNTER_POWER_PERCENT_PREFIX + "11", 1000);
assertMetricsLog(BatterySavingStats.COUNTER_TIME_SECONDS_PREFIX + "11", 60 * 10);
target.advanceClock(1);
@@ -305,6 +313,7 @@
target.startCharging();
assertMetricsLog(BatterySavingStats.COUNTER_POWER_MILLIAMPS_PREFIX + "10", 2);
+ assertMetricsLog(BatterySavingStats.COUNTER_POWER_PERCENT_PREFIX + "10", 200);
assertMetricsLog(BatterySavingStats.COUNTER_TIME_SECONDS_PREFIX + "10", 60);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
new file mode 100644
index 0000000..51b019a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -0,0 +1,50 @@
+package com.android.server.wm;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for the {@link RootWindowContainer} class.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:com.android.server.wm.RootWindowContainerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RootWindowContainerTests extends WindowTestsBase {
+ @Test
+ public void testSetDisplayOverrideConfigurationIfNeeded() throws Exception {
+ // Add first stack we expect to be updated with configuration change.
+ final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
+ stack.getOverrideConfiguration().windowConfiguration.setBounds(new Rect(0, 0, 5, 5));
+
+ // Add second task that will be set for deferred removal that should not be returned
+ // with the configuration change.
+ final TaskStack deferredDeletedStack = createTaskStackOnDisplay(mDisplayContent);
+ deferredDeletedStack.getOverrideConfiguration().windowConfiguration.setBounds(
+ new Rect(0, 0, 5, 5));
+ deferredDeletedStack.mDeferRemoval = true;
+
+ final Configuration override = new Configuration(
+ mDisplayContent.getOverrideConfiguration());
+ override.windowConfiguration.setBounds(new Rect(0, 0, 10, 10));
+
+ // Set display override.
+ final int[] results = sWm.mRoot.setDisplayOverrideConfigurationIfNeeded(override,
+ mDisplayContent.getDisplayId());
+
+ // Ensure only first stack is returned.
+ assertTrue(results.length == 1);
+ assertTrue(results[0] == stack.mStackId);
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java
index 7c14d08..b784c60 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceFullAccessListTest.java
@@ -67,6 +67,15 @@
}
@Test
+ public void testRemoveAccess() {
+ mAccessList.grantFullAccess("pkg", 0);
+ assertTrue(mAccessList.hasFullAccess("pkg", 0));
+
+ mAccessList.removeGrant("pkg", 0);
+ assertFalse(mAccessList.hasFullAccess("pkg", 0));
+ }
+
+ @Test
public void testSerialization() throws XmlPullParserException, IOException {
mAccessList.grantFullAccess("pkg", 0);
mAccessList.grantFullAccess("pkg1", 0);