Merge "Fix "auto battery saver" confirmation dialog button layout" into pi-dev
diff --git a/api/current.txt b/api/current.txt
index 83092f6..607109d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -38395,17 +38395,17 @@
package android.se.omapi {
- public class Channel {
+ public final class Channel implements java.nio.channels.Channel {
method public void close();
method public byte[] getSelectResponse();
method public android.se.omapi.Session getSession();
method public boolean isBasicChannel();
- method public boolean isClosed();
+ method public boolean isOpen();
method public boolean selectNext() throws java.io.IOException;
method public byte[] transmit(byte[]) throws java.io.IOException;
}
- public class Reader {
+ public final class Reader {
method public void closeSessions();
method public java.lang.String getName();
method public android.se.omapi.SEService getSEService();
@@ -38413,26 +38413,28 @@
method public android.se.omapi.Session openSession() throws java.io.IOException;
}
- public class SEService {
- ctor public SEService(android.content.Context, android.se.omapi.SEService.SecureElementListener);
+ public final class SEService {
+ ctor public SEService(android.content.Context, java.util.concurrent.Executor, android.se.omapi.SEService.OnConnectedListener);
method public android.se.omapi.Reader[] getReaders();
method public java.lang.String getVersion();
method public boolean isConnected();
method public void shutdown();
}
- public static abstract interface SEService.SecureElementListener {
- method public abstract void onServiceConnected();
+ public static abstract interface SEService.OnConnectedListener {
+ method public abstract void onConnected();
}
- public class Session {
+ public final class Session {
method public void close();
method public void closeChannels();
method public byte[] getATR();
method public android.se.omapi.Reader getReader();
method public boolean isClosed();
method public android.se.omapi.Channel openBasicChannel(byte[], byte) throws java.io.IOException;
+ method public android.se.omapi.Channel openBasicChannel(byte[]) throws java.io.IOException;
method public android.se.omapi.Channel openLogicalChannel(byte[], byte) throws java.io.IOException;
+ method public android.se.omapi.Channel openLogicalChannel(byte[]) throws java.io.IOException;
}
}
@@ -40955,7 +40957,7 @@
method public final void putExtras(android.os.Bundle);
method public final void removeExtras(java.util.List<java.lang.String>);
method public final void removeExtras(java.lang.String...);
- method public void requestBluetoothAudio(java.lang.String);
+ method public void requestBluetoothAudio(android.bluetooth.BluetoothDevice);
method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
method public final void sendRemoteRttRequest();
method public final void sendRttInitiationFailure(int);
@@ -41166,7 +41168,7 @@
method public void onCanAddCallChanged(boolean);
method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
method public void onSilenceRinger();
- method public final void requestBluetoothAudio(java.lang.String);
+ method public final void requestBluetoothAudio(android.bluetooth.BluetoothDevice);
method public final void setAudioRoute(int);
method public final void setMuted(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
diff --git a/cmds/statsd/benchmark/metric_util.cpp b/cmds/statsd/benchmark/metric_util.cpp
index 50b05cd..fae186a 100644
--- a/cmds/statsd/benchmark/metric_util.cpp
+++ b/cmds/statsd/benchmark/metric_util.cpp
@@ -366,7 +366,7 @@
sp<AlarmMonitor> periodicAlarmMonitor;
sp<StatsLogProcessor> processor = new StatsLogProcessor(
uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseSec, [](const ConfigKey&){});
- processor->OnConfigUpdated(key, config);
+ processor->OnConfigUpdated(0, key, config);
return processor;
}
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 13f2679..f00cdb3 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -191,11 +191,12 @@
}
}
-void StatsLogProcessor::OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) {
+void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
+ const StatsdConfig& config) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
VLOG("Updated configuration for key %s", key.ToString().c_str());
sp<MetricsManager> newMetricsManager =
- new MetricsManager(key, config, mTimeBaseSec, mUidMap,
+ new MetricsManager(key, config, mTimeBaseSec, (timestampNs - 1) / NS_PER_SEC + 1, mUidMap,
mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
if (newMetricsManager->isConfigValid()) {
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 387a929..1c4698f 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -42,7 +42,8 @@
void OnLogEvent(LogEvent* event);
- void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config);
+ void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
+ const StatsdConfig& config);
void OnConfigRemoved(const ConfigKey& key);
size_t GetMetricsSize(const ConfigKey& key) const;
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
index 249cb59..70e6e84 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.cpp
+++ b/cmds/statsd/src/anomaly/AlarmTracker.cpp
@@ -30,7 +30,8 @@
namespace os {
namespace statsd {
-AlarmTracker::AlarmTracker(uint64_t startMillis,
+AlarmTracker::AlarmTracker(const uint64_t startMillis,
+ const uint64_t currentMillis,
const Alarm& alarm, const ConfigKey& configKey,
const sp<AlarmMonitor>& alarmMonitor)
: mAlarmConfig(alarm),
@@ -38,7 +39,11 @@
mAlarmMonitor(alarmMonitor) {
VLOG("AlarmTracker() called");
mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC;
+ // startMillis is the time statsd is created. We need to find the 1st alarm timestamp after
+ // the config is added to statsd.
+ mAlarmSec = findNextAlarmSec(currentMillis / MS_PER_SEC); // round up
mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
+ VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
if (mAlarmMonitor != nullptr) {
mAlarmMonitor->add(mInternalAlarm);
}
@@ -55,9 +60,13 @@
mSubscriptions.push_back(subscription);
}
-uint64_t AlarmTracker::findNextAlarmSec(uint64_t currentTimeSec) {
- int periodsForward = (currentTimeSec - mAlarmSec) * MS_PER_SEC / mAlarmConfig.period_millis();
- return mAlarmSec + (periodsForward + 1) * mAlarmConfig.period_millis() / MS_PER_SEC;
+int64_t AlarmTracker::findNextAlarmSec(int64_t currentTimeSec) {
+ if (currentTimeSec <= mAlarmSec) {
+ return mAlarmSec;
+ }
+ int64_t periodsForward =
+ ((currentTimeSec - mAlarmSec) * MS_PER_SEC - 1) / mAlarmConfig.period_millis() + 1;
+ return mAlarmSec + periodsForward * mAlarmConfig.period_millis() / MS_PER_SEC;
}
void AlarmTracker::informAlarmsFired(
@@ -68,12 +77,14 @@
return;
}
if (!mSubscriptions.empty()) {
+ VLOG("AlarmTracker triggers the subscribers.");
triggerSubscribers(mAlarmConfig.id(), DEFAULT_METRIC_DIMENSION_KEY, mConfigKey,
mSubscriptions);
}
firedAlarms.erase(mInternalAlarm);
mAlarmSec = findNextAlarmSec((timestampNs-1) / NS_PER_SEC + 1); // round up
mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
+ VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
if (mAlarmMonitor != nullptr) {
mAlarmMonitor->add(mInternalAlarm);
}
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
index 13180a5..962a014 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.h
+++ b/cmds/statsd/src/anomaly/AlarmTracker.h
@@ -34,7 +34,8 @@
class AlarmTracker : public virtual RefBase {
public:
- AlarmTracker(uint64_t startMillis,
+ AlarmTracker(const uint64_t startMillis,
+ const uint64_t currentMillis,
const Alarm& alarm, const ConfigKey& configKey,
const sp<AlarmMonitor>& subscriberAlarmMonitor);
@@ -53,13 +54,13 @@
return mInternalAlarm == nullptr ? 0 : mInternalAlarm->timestampSec;
}
- uint64_t findNextAlarmSec(uint64_t currentTimeMillis);
+ int64_t findNextAlarmSec(int64_t currentTimeMillis);
// statsd_config.proto Alarm message that defines this tracker.
const Alarm mAlarmConfig;
// A reference to the Alarm's config key.
- const ConfigKey& mConfigKey;
+ const ConfigKey mConfigKey;
// The subscriptions that depend on this alarm.
std::vector<Subscription> mSubscriptions;
@@ -68,7 +69,7 @@
sp<AlarmMonitor> mAlarmMonitor;
// The current expected alarm time in seconds.
- uint64_t mAlarmSec;
+ int64_t mAlarmSec;
// The current alarm.
sp<const InternalAlarm> mInternalAlarm;
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h
index ae0af64..15671a6 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.h
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.h
@@ -127,7 +127,7 @@
std::vector<Subscription> mSubscriptions;
// A reference to the Alert's config key.
- const ConfigKey& mConfigKey;
+ const ConfigKey mConfigKey;
// Number of past buckets. One less than the total number of buckets needed
// for the anomaly detection (since the current bucket is not in the past).
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 5bb2015..ab9c7e8 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -108,7 +108,7 @@
ResourceConfigurationChanged resource_configuration_changed = 66;
BluetoothEnabledStateChanged bluetooth_enabled_state_changed = 67;
BluetoothConnectionStateChanged bluetooth_connection_state_changed = 68;
- BluetoothA2dpAudioStateChanged bluetooth_a2dp_audio_state_changed = 69;
+ // 69 is blank but need not be.
UsbConnectorStateChanged usb_connector_state_changed = 70;
SpeakerImpedanceReported speaker_impedance_reported = 71;
HardwareFailed hardware_failed = 72;
@@ -1008,22 +1008,6 @@
}
/**
- * Logs when Bluetooth A2dp audio streaming state changes.
- *
- * Logged from:
- * TODO(b/73971848)
- */
-message BluetoothA2dpAudioStateChanged {
- // Whether or not audio is being played using Bluetooth A2dp.
- enum State {
- UNKNOWN = 0;
- PLAY = 1;
- STOP = 2;
- }
- optional State state = 1;
-}
-
-/**
* Logs when something is plugged into or removed from the USB-C connector.
*
* Logged from:
diff --git a/cmds/statsd/src/config/ConfigListener.h b/cmds/statsd/src/config/ConfigListener.h
index 19ccfcf..54e7770 100644
--- a/cmds/statsd/src/config/ConfigListener.h
+++ b/cmds/statsd/src/config/ConfigListener.h
@@ -40,7 +40,8 @@
/**
* A configuration was added or updated.
*/
- virtual void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) = 0;
+ virtual void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
+ const StatsdConfig& config) = 0;
/**
* A configuration was removed.
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index ff25091..f9aaad4 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -21,6 +21,7 @@
#include "storage/StorageManager.h"
#include "guardrail/StatsdStats.h"
+#include "stats_log_util.h"
#include "stats_util.h"
#include <android-base/file.h>
@@ -109,9 +110,10 @@
}
}
+ const int64_t timestampNs = getElapsedRealtimeNs();
// Tell everyone
for (sp<ConfigListener> listener:broadcastList) {
- listener->OnConfigUpdated(key, config);
+ listener->OnConfigUpdated(timestampNs, key, config);
}
}
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 00188e8..c61fa76 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -49,7 +49,7 @@
const int FIELD_ID_METRICS = 1;
MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
- const long timeBaseSec,
+ const long timeBaseSec, const long currentTimeSec,
const sp<UidMap> &uidMap,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor)
@@ -58,7 +58,7 @@
mLastReportWallClockNs(getWallClockNs()) {
mConfigValid =
initStatsdConfig(key, config, *uidMap, anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, mTagIds, mAllAtomMatchers,
+ timeBaseSec, currentTimeSec, mTagIds, mAllAtomMatchers,
mAllConditionTrackers, mAllMetricProducers, mAllAnomalyTrackers,
mAllPeriodicAlarmTrackers, mConditionToMetricMap, mTrackerToMetricMap,
mTrackerToConditionMap, mNoReportMetricIds);
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index da0cd4a..4fd64b7 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -36,7 +36,8 @@
// A MetricsManager is responsible for managing metrics from one single config source.
class MetricsManager : public PackageInfoListener {
public:
- MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const long timeBaseSec,
+ MetricsManager(const ConfigKey& configKey, const StatsdConfig& config,
+ const long timeBaseSec, const long currentTimeSec,
const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor);
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 50eca05..b7c5795 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -599,10 +599,11 @@
bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
const sp<AlarmMonitor>& periodicAlarmMonitor,
- const long timeBaseSec,
+ const long timeBaseSec, const long currentTimeSec,
vector<sp<AlarmTracker>>& allAlarmTrackers) {
unordered_map<int64_t, int> alarmTrackerMap;
uint64_t startMillis = (uint64_t)timeBaseSec * MS_PER_SEC;
+ uint64_t currentTimeMillis = (uint64_t)currentTimeSec * MS_PER_SEC;
for (int i = 0; i < config.alarm_size(); i++) {
const Alarm& alarm = config.alarm(i);
if (alarm.offset_millis() <= 0) {
@@ -615,7 +616,8 @@
}
alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
allAlarmTrackers.push_back(
- new AlarmTracker(startMillis, alarm, key, periodicAlarmMonitor));
+ new AlarmTracker(startMillis, currentTimeMillis,
+ alarm, key, periodicAlarmMonitor));
}
for (int i = 0; i < config.subscription_size(); ++i) {
const Subscription& subscription = config.subscription(i);
@@ -644,7 +646,7 @@
const UidMap& uidMap,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor,
- const long timeBaseSec,
+ const long timeBaseSec, const long currentTimeSec,
set<int>& allTagIds,
vector<sp<LogMatchingTracker>>& allAtomMatchers,
vector<sp<ConditionTracker>>& allConditionTrackers,
@@ -682,7 +684,8 @@
ALOGE("initAlerts failed");
return false;
}
- if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseSec, allPeriodicAlarmTrackers)) {
+ if (!initAlarms(config, key, periodicAlarmMonitor,
+ timeBaseSec, currentTimeSec, allPeriodicAlarmTrackers)) {
ALOGE("initAlarms failed");
return false;
}
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
index 386de0b..3754ae0 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -98,7 +98,7 @@
const UidMap& uidMap,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor,
- const long timeBaseSec,
+ const long timeBaseSec, const long currentTimeSec,
std::set<int>& allTagIds,
std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
std::vector<sp<ConditionTracker>>& allConditionTrackers,
diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp
index 838745e..9455304 100644
--- a/cmds/statsd/tests/ConfigManager_test.cpp
+++ b/cmds/statsd/tests/ConfigManager_test.cpp
@@ -44,7 +44,8 @@
*/
class MockListener : public ConfigListener {
public:
- MOCK_METHOD2(OnConfigUpdated, void(const ConfigKey& key, const StatsdConfig& config));
+ MOCK_METHOD3(OnConfigUpdated, void(const int64_t timestampNs, const ConfigKey& key,
+ const StatsdConfig& config));
MOCK_METHOD1(OnConfigRemoved, void(const ConfigKey& key));
};
@@ -88,25 +89,25 @@
manager->StartupForTest();
// Add another one
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, StringToId("zzz")),
+ EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
StatsdConfigEq(91)))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config91);
// Update It
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, StringToId("zzz")),
+ EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
StatsdConfigEq(92)))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config92);
// Add one with the same uid but a different name
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, StringToId("yyy")),
+ EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("yyy")),
StatsdConfigEq(93)))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("yyy")), config93);
// Add one with the same name but a different uid
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(2, StringToId("zzz")),
+ EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(2, StringToId("zzz")),
StatsdConfigEq(94)))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config94);
@@ -142,7 +143,7 @@
StatsdConfig config;
- EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _)).Times(5);
+ EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _, _)).Times(5);
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("xxx"))));
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("yyy"))));
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))));
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index 5d8c3f7..07378db 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -287,7 +287,7 @@
EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, allTagIds, allAtomMatchers,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -315,7 +315,7 @@
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, allTagIds, allAtomMatchers,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -340,7 +340,7 @@
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, allTagIds, allAtomMatchers,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -364,7 +364,7 @@
std::set<int64_t> noReportMetricIds;
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, allTagIds, allAtomMatchers,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -388,7 +388,7 @@
std::set<int64_t> noReportMetricIds;
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, allTagIds, allAtomMatchers,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -413,7 +413,7 @@
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, allTagIds, allAtomMatchers,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -438,7 +438,7 @@
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
- timeBaseSec, allTagIds, allAtomMatchers,
+ timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 4b9a87d..5a8ba79 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -43,7 +43,7 @@
class MockMetricsManager : public MetricsManager {
public:
MockMetricsManager() : MetricsManager(
- ConfigKey(1, 12345), StatsdConfig(), 1000,
+ ConfigKey(1, 12345), StatsdConfig(), 1000, 1000,
new UidMap(),
new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
[](const sp<IStatsCompanionService>&){}),
@@ -135,7 +135,7 @@
ConfigKey key(3, 4);
StatsdConfig config;
config.add_allowed_log_source("AID_ROOT");
- p.OnConfigUpdated(key, config);
+ p.OnConfigUpdated(0, key, config);
// Expect to get no metrics, but snapshot specified above in uidmap.
vector<uint8_t> bytes;
diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
index 3330ee9..5e6de1c 100644
--- a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
@@ -39,25 +39,24 @@
Alarm alarm;
alarm.set_offset_millis(15 * MS_PER_SEC);
alarm.set_period_millis(60 * 60 * MS_PER_SEC); // 1hr
- uint64_t startMillis = 100000000 * MS_PER_SEC;
- AlarmTracker tracker(startMillis, alarm, kConfigKey,
- subscriberAlarmMonitor);
+ int64_t startMillis = 100000000 * MS_PER_SEC;
+ AlarmTracker tracker(startMillis, startMillis, alarm, kConfigKey, subscriberAlarmMonitor);
- EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15);
+ EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15));
uint64_t currentTimeSec = startMillis / MS_PER_SEC + 10;
std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarmSet =
subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
EXPECT_TRUE(firedAlarmSet.empty());
tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
- EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15);
+ EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15));
currentTimeSec = startMillis / MS_PER_SEC + 7000;
firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
EXPECT_EQ(firedAlarmSet.size(), 1u);
tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
EXPECT_TRUE(firedAlarmSet.empty());
- EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15 + 2 * 60 * 60);
+ EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15 + 2 * 60 * 60));
}
} // namespace statsd
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index d0840f0..0acd297 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -455,7 +455,7 @@
[](const sp<IStatsCompanionService>&){});
sp<StatsLogProcessor> processor = new StatsLogProcessor(
uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseSec, [](const ConfigKey&){});
- processor->OnConfigUpdated(key, config);
+ processor->OnConfigUpdated(timeBaseSec, key, config);
return processor;
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index ddd0656..5067e19 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -73,6 +73,7 @@
ParceledListSlice getNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted);
int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted);
int getDeletedChannelCount(String pkg, int uid);
+ int getBlockedChannelCount(String pkg, int uid);
void deleteNotificationChannelGroup(String pkg, String channelGroupId);
NotificationChannelGroup getNotificationChannelGroup(String pkg, String channelGroupId);
ParceledListSlice getNotificationChannelGroups(String pkg);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 1776eac..95e4f93 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -279,12 +279,12 @@
}});
registerService(Context.IPSEC_SERVICE, IpSecManager.class,
- new StaticServiceFetcher<IpSecManager>() {
+ new CachedServiceFetcher<IpSecManager>() {
@Override
- public IpSecManager createService() {
+ public IpSecManager createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getService(Context.IPSEC_SERVICE);
IIpSecService service = IIpSecService.Stub.asInterface(b);
- return new IpSecManager(service);
+ return new IpSecManager(ctx, service);
}});
registerService(Context.COUNTRY_DETECTOR, CountryDetector.class,
diff --git a/core/java/android/net/IIpSecService.aidl b/core/java/android/net/IIpSecService.aidl
index 3a3ddcc..d6774d4 100644
--- a/core/java/android/net/IIpSecService.aidl
+++ b/core/java/android/net/IIpSecService.aidl
@@ -45,25 +45,31 @@
in String localAddr,
in String remoteAddr,
in Network underlyingNetwork,
- in IBinder binder);
+ in IBinder binder,
+ in String callingPackage);
void addAddressToTunnelInterface(
int tunnelResourceId,
- in LinkAddress localAddr);
+ in LinkAddress localAddr,
+ in String callingPackage);
void removeAddressFromTunnelInterface(
int tunnelResourceId,
- in LinkAddress localAddr);
+ in LinkAddress localAddr,
+ in String callingPackage);
- void deleteTunnelInterface(int resourceId);
+ void deleteTunnelInterface(int resourceId, in String callingPackage);
- IpSecTransformResponse createTransform(in IpSecConfig c, in IBinder binder);
+ IpSecTransformResponse createTransform(
+ in IpSecConfig c, in IBinder binder, in String callingPackage);
void deleteTransform(int transformId);
- void applyTransportModeTransform(in ParcelFileDescriptor socket, int direction, int transformId);
+ void applyTransportModeTransform(
+ in ParcelFileDescriptor socket, int direction, int transformId);
- void applyTunnelModeTransform(int tunnelResourceId, int direction, int transformResourceId);
+ void applyTunnelModeTransform(
+ int tunnelResourceId, int direction, int transformResourceId, in String callingPackage);
void removeTransportModeTransforms(in ParcelFileDescriptor socket);
}
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 1525508..e0654fd 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -140,6 +140,7 @@
}
}
+ private final Context mContext;
private final IIpSecService mService;
/**
@@ -661,6 +662,7 @@
*/
@SystemApi
public static final class IpSecTunnelInterface implements AutoCloseable {
+ private final String mOpPackageName;
private final IIpSecService mService;
private final InetAddress mRemoteAddress;
private final InetAddress mLocalAddress;
@@ -688,7 +690,8 @@
@RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
public void addAddress(@NonNull LinkAddress address) throws IOException {
try {
- mService.addAddressToTunnelInterface(mResourceId, address);
+ mService.addAddressToTunnelInterface(
+ mResourceId, address, mOpPackageName);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -706,16 +709,18 @@
@RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS)
public void removeAddress(@NonNull LinkAddress address) throws IOException {
try {
- mService.removeAddressFromTunnelInterface(mResourceId, address);
+ mService.removeAddressFromTunnelInterface(
+ mResourceId, address, mOpPackageName);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
- private IpSecTunnelInterface(@NonNull IIpSecService service,
+ private IpSecTunnelInterface(@NonNull Context ctx, @NonNull IIpSecService service,
@NonNull InetAddress localAddress, @NonNull InetAddress remoteAddress,
@NonNull Network underlyingNetwork)
throws ResourceUnavailableException, IOException {
+ mOpPackageName = ctx.getOpPackageName();
mService = service;
mLocalAddress = localAddress;
mRemoteAddress = remoteAddress;
@@ -727,7 +732,8 @@
localAddress.getHostAddress(),
remoteAddress.getHostAddress(),
underlyingNetwork,
- new Binder());
+ new Binder(),
+ mOpPackageName);
switch (result.status) {
case Status.OK:
break;
@@ -756,7 +762,7 @@
@Override
public void close() {
try {
- mService.deleteTunnelInterface(mResourceId);
+ mService.deleteTunnelInterface(mResourceId, mOpPackageName);
mResourceId = INVALID_RESOURCE_ID;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -801,7 +807,8 @@
public IpSecTunnelInterface createIpSecTunnelInterface(@NonNull InetAddress localAddress,
@NonNull InetAddress remoteAddress, @NonNull Network underlyingNetwork)
throws ResourceUnavailableException, IOException {
- return new IpSecTunnelInterface(mService, localAddress, remoteAddress, underlyingNetwork);
+ return new IpSecTunnelInterface(
+ mContext, mService, localAddress, remoteAddress, underlyingNetwork);
}
/**
@@ -827,7 +834,8 @@
@PolicyDirection int direction, @NonNull IpSecTransform transform) throws IOException {
try {
mService.applyTunnelModeTransform(
- tunnel.getResourceId(), direction, transform.getResourceId());
+ tunnel.getResourceId(), direction,
+ transform.getResourceId(), mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -839,7 +847,8 @@
* @param context the application context for this manager
* @hide
*/
- public IpSecManager(IIpSecService service) {
+ public IpSecManager(Context ctx, IIpSecService service) {
+ mContext = ctx;
mService = checkNotNull(service, "missing service");
}
}
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index 099fe02..fb5f46c 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -130,7 +130,8 @@
synchronized (this) {
try {
IIpSecService svc = getIpSecService();
- IpSecTransformResponse result = svc.createTransform(mConfig, new Binder());
+ IpSecTransformResponse result = svc.createTransform(
+ mConfig, new Binder(), mContext.getOpPackageName());
int status = result.status;
checkResultStatus(status);
mResourceId = result.resourceId;
diff --git a/core/java/android/se/omapi/Channel.java b/core/java/android/se/omapi/Channel.java
index c8efede..5db3c1a 100644
--- a/core/java/android/se/omapi/Channel.java
+++ b/core/java/android/se/omapi/Channel.java
@@ -39,7 +39,7 @@
*
* @see <a href="http://globalplatform.org">GlobalPlatform Open Mobile API</a>
*/
-public class Channel {
+public final class Channel implements java.nio.channels.Channel {
private static final String TAG = "OMAPI.Channel";
private Session mSession;
@@ -64,7 +64,7 @@
* before closing the channel.
*/
public void close() {
- if (!isClosed()) {
+ if (isOpen()) {
synchronized (mLock) {
try {
mChannel.close();
@@ -76,21 +76,21 @@
}
/**
- * Tells if this channel is closed.
+ * Tells if this channel is open.
*
- * @return <code>true</code> if the channel is closed or in case of an error.
- * <code>false</code> otherwise.
+ * @return <code>false</code> if the channel is closed or in case of an error.
+ * <code>true</code> otherwise.
*/
- public boolean isClosed() {
+ public boolean isOpen() {
if (!mService.isConnected()) {
Log.e(TAG, "service not connected to system");
- return true;
+ return false;
}
try {
- return mChannel.isClosed();
+ return !mChannel.isClosed();
} catch (RemoteException e) {
Log.e(TAG, "Exception in isClosed()");
- return true;
+ return false;
}
}
diff --git a/core/java/android/se/omapi/Reader.java b/core/java/android/se/omapi/Reader.java
index 9be3da6..80262f7 100644
--- a/core/java/android/se/omapi/Reader.java
+++ b/core/java/android/se/omapi/Reader.java
@@ -37,7 +37,7 @@
*
* @see <a href="http://globalplatform.org">GlobalPlatform Open Mobile API</a>
*/
-public class Reader {
+public final class Reader {
private static final String TAG = "OMAPI.Reader";
private final String mName;
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
index 311dc4c..14727f0 100644
--- a/core/java/android/se/omapi/SEService.java
+++ b/core/java/android/se/omapi/SEService.java
@@ -32,6 +32,7 @@
import android.util.Log;
import java.util.HashMap;
+import java.util.concurrent.Executor;
/**
* The SEService realises the communication to available Secure Elements on the
@@ -40,7 +41,7 @@
*
* @see <a href="http://simalliance.org">SIMalliance Open Mobile API v3.0</a>
*/
-public class SEService {
+public final class SEService {
/**
* Error code used with ServiceSpecificException.
@@ -62,11 +63,11 @@
/**
* Interface to send call-backs to the application when the service is connected.
*/
- public interface SecureElementListener {
+ public interface OnConnectedListener {
/**
* Called by the framework when the service is connected.
*/
- void onServiceConnected();
+ void onConnected();
}
/**
@@ -74,16 +75,22 @@
* SEService could be bound to the backend.
*/
private class SEListener extends ISecureElementListener.Stub {
- public SecureElementListener mListener = null;
+ public OnConnectedListener mListener = null;
+ public Executor mExecutor = null;
@Override
public IBinder asBinder() {
return this;
}
- public void onServiceConnected() {
- if (mListener != null) {
- mListener.onServiceConnected();
+ public void onConnected() {
+ if (mListener != null && mExecutor != null) {
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onConnected();
+ }
+ });
}
}
}
@@ -116,22 +123,26 @@
* the specified listener is called or if isConnected() returns
* <code>true</code>. <br>
* The call-back object passed as a parameter will have its
- * onServiceConnected() method called when the connection actually happen.
+ * onConnected() method called when the connection actually happen.
*
* @param context
* the context of the calling application. Cannot be
* <code>null</code>.
* @param listener
- * a SecureElementListener object.
+ * a OnConnectedListener object.
+ * @param executor
+ * an Executor which will be used when invoking the callback.
*/
- public SEService(@NonNull Context context, @NonNull SecureElementListener listener) {
+ public SEService(@NonNull Context context, @NonNull Executor executor,
+ @NonNull OnConnectedListener listener) {
- if (context == null) {
- throw new NullPointerException("context must not be null");
+ if (context == null || listener == null || executor == null) {
+ throw new NullPointerException("Arguments must not be null");
}
mContext = context;
mSEListener.mListener = listener;
+ mSEListener.mExecutor = executor;
mConnection = new ServiceConnection() {
@@ -140,7 +151,7 @@
mSecureElementService = ISecureElementService.Stub.asInterface(service);
if (mSEListener != null) {
- mSEListener.onServiceConnected();
+ mSEListener.onConnected();
}
Log.i(TAG, "Service onServiceConnected");
}
@@ -171,12 +182,12 @@
}
/**
- * Returns the list of available Secure Element readers.
+ * Returns an array of available Secure Element readers.
* There must be no duplicated objects in the returned list.
* All available readers shall be listed even if no card is inserted.
*
- * @return The readers list, as an array of Readers. If there are no
- * readers the returned array is of length 0.
+ * @return An array of Readers. If there are no readers the returned array
+ * is of length 0.
*/
public @NonNull Reader[] getReaders() {
if (mSecureElementService == null) {
@@ -212,7 +223,8 @@
* (including any binding to an underlying service).
* As a result isConnected() will return false after shutdown() was called.
* After this method call, the SEService object is not connected.
- * It is recommended to call this method in the termination method of the calling application
+ * This method should be called when connection to the Secure Element is not needed
+ * or in the termination method of the calling application
* (or part of this application) which is bound to this SEService.
*/
public void shutdown() {
diff --git a/core/java/android/se/omapi/Session.java b/core/java/android/se/omapi/Session.java
index adfeddd..d5f8c82 100644
--- a/core/java/android/se/omapi/Session.java
+++ b/core/java/android/se/omapi/Session.java
@@ -39,7 +39,7 @@
*
* @see <a href="http://simalliance.org">SIMalliance Open Mobile API v3.0</a>
*/
-public class Session {
+public final class Session {
private final Object mLock = new Object();
private final SEService mService;
@@ -225,6 +225,32 @@
}
/**
+ * This method is provided to ease the development of mobile application and for compliancy
+ * with existing applications.
+ * This method is equivalent to openBasicChannel(aid, P2=0x00)
+ *
+ * @param aid the AID of the Applet to be selected on this channel, as a
+ * byte array, or null if no Applet is to be selected.
+ * @throws IOException if there is a communication problem to the reader or
+ * the Secure Element.
+ * @throws IllegalStateException if the Secure Element session is used after
+ * being closed.
+ * @throws IllegalArgumentException if the aid's length is not within 5 to
+ * 16 (inclusive).
+ * @throws SecurityException if the calling application cannot be granted
+ * access to this AID or the default Applet on this
+ * session.
+ * @throws NoSuchElementException if the AID on the Secure Element is not available or cannot be
+ * selected.
+ * @throws UnsupportedOperationException if the given P2 parameter is not
+ * supported by the device
+ * @return an instance of Channel if available or null.
+ */
+ public @Nullable Channel openBasicChannel(@Nullable byte[] aid) throws IOException {
+ return openBasicChannel(aid, (byte) 0x00);
+ }
+
+ /**
* Open a logical channel with the Secure Element, selecting the Applet represented by
* the given AID. If the AID is null, which means no Applet is to be selected on this
* channel, the default Applet is used. It's up to the Secure Element to choose which
@@ -304,4 +330,32 @@
}
}
}
+
+ /**
+ * This method is provided to ease the development of mobile application and for compliancy
+ * with existing applications.
+ * This method is equivalent to openLogicalChannel(aid, P2=0x00)
+ *
+ * @param aid the AID of the Applet to be selected on this channel, as a
+ * byte array.
+ * @throws IOException if there is a communication problem to the reader or
+ * the Secure Element.
+ * @throws IllegalStateException if the Secure Element is used after being
+ * closed.
+ * @throws IllegalArgumentException if the aid's length is not within 5 to
+ * 16 (inclusive).
+ * @throws SecurityException if the calling application cannot be granted
+ * access to this AID or the default Applet on this
+ * session.
+ * @throws NoSuchElementException if the AID on the Secure Element is not
+ * available or cannot be selected or a logical channel is already
+ * open to a non-multiselectable Applet.
+ * @throws UnsupportedOperationException if the given P2 parameter is not
+ * supported by the device.
+ * @return an instance of Channel. Null if the Secure Element is unable to
+ * provide a new logical channel.
+ */
+ public @Nullable Channel openLogicalChannel(@Nullable byte[] aid) throws IOException {
+ return openLogicalChannel(aid, (byte) 0x00);
+ }
}
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
new file mode 100644
index 0000000..ed42e2e
--- /dev/null
+++ b/core/proto/OWNERS
@@ -0,0 +1,13 @@
+# Be sure you are familiar with proto when you modify this directory.
+
+# Metrics
+bookatz@google.com
+cjyu@google.com
+jinyithu@google.com
+joeo@google.com
+kwekua@google.com
+singhtejinder@google.com
+
+# Frameworks
+ogunwale@google.com
+jjaggi@google.com
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f4715fc..04c4130 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4248,6 +4248,11 @@
android:exported="false">
</receiver>
+ <receiver android:name="com.android.server.stats.StatsCompanionService$PeriodicAlarmReceiver"
+ android:permission="android.permission.STATSCOMPANION"
+ android:exported="false">
+ </receiver>
+
<receiver android:name="com.android.server.am.BatteryStatsService$UsbConnectionReceiver"
android:exported="false">
<intent-filter>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index eebf581..02d6c9f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1205,7 +1205,6 @@
<java-symbol type="string" name="ssl_ca_cert_noti_by_administrator" />
<java-symbol type="string" name="ssl_ca_cert_noti_managed" />
<java-symbol type="string" name="work_profile_deleted" />
- <java-symbol type="string" name="work_profile_deleted_description" />
<java-symbol type="string" name="work_profile_deleted_details" />
<java-symbol type="string" name="work_profile_deleted_description_dpm_wipe" />
<java-symbol type="string" name="work_profile_deleted_reason_maximum_password_failure" />
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index 32d4c77..3ca9295 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -151,7 +151,12 @@
mGrContext->freeGpuResources();
break;
case TrimMemoryMode::UiHidden:
- mGrContext->purgeUnlockedResources(mMaxResourceBytes - mBackgroundResourceBytes, true);
+ // Here we purge all the unlocked scratch resources and then toggle the resources cache
+ // limits between the background and max amounts. This causes the unlocked resources
+ // that have persistent data to be purged in LRU order.
+ mGrContext->purgeUnlockedResources(true);
+ mGrContext->setResourceCacheLimits(mMaxResources, mBackgroundResourceBytes);
+ mGrContext->setResourceCacheLimits(mMaxResources, mMaxResourceBytes);
break;
}
}
@@ -161,7 +166,10 @@
return;
}
mGrContext->flush();
- mGrContext->purgeResourcesNotUsedInMs(std::chrono::seconds(30));
+ // Here we purge all the unlocked scratch resources (leaving those resources w/ persistent data)
+ // and then purge those w/ persistent data based on age.
+ mGrContext->purgeUnlockedResources(true);
+ mGrContext->purgeResourcesNotUsedInMs(std::chrono::seconds(10));
}
sp<skiapipeline::VectorDrawableAtlas> CacheManager::acquireVectorDrawableAtlas() {
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
index b1106f0..c235715 100644
--- a/libs/hwui/tests/unit/CacheManagerTests.cpp
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -20,6 +20,8 @@
#include "renderthread/EglManager.h"
#include "tests/common/TestUtils.h"
+#include <SkImagePriv.h>
+
using namespace android;
using namespace android::uirenderer;
using namespace android::uirenderer::renderthread;
@@ -49,7 +51,12 @@
surfaces.push_back(surface);
}
- ASSERT_TRUE(1 < surfaces.size());
+ // create an image and pin it so that we have something with a unique key in the cache
+ sk_sp<Bitmap> bitmap =
+ Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(displayInfo.w, displayInfo.h));
+ sk_sp<SkColorFilter> filter;
+ sk_sp<SkImage> image = bitmap->makeImage(&filter);
+ ASSERT_TRUE(SkImage_pinAsTexture(image.get(), grContext));
// attempt to trim all memory while we still hold strong refs
renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
@@ -61,11 +68,14 @@
surfaces[i].reset();
}
+ // unpin the image which should add a unique purgeable key to the cache
+ SkImage_unpinAsTexture(image.get(), grContext);
+
// verify that we have enough purgeable bytes
const size_t purgeableBytes = grContext->getResourceCachePurgeableBytes();
ASSERT_TRUE(renderThread.cacheManager().getBackgroundCacheSize() < purgeableBytes);
- // UI hidden and make sure only some got purged
+ // UI hidden and make sure only some got purged (unique should remain)
renderThread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
ASSERT_TRUE(0 < grContext->getResourceCachePurgeableBytes());
ASSERT_TRUE(renderThread.cacheManager().getBackgroundCacheSize() > getCacheUsage(grContext));
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index fa3f99a..1276881 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -89,6 +89,10 @@
ProviderProperties getProviderProperties(String provider);
String getNetworkProviderPackage();
+ 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);
void setTestProviderLocation(String provider, in Location loc, String opPackageName);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index a523958..38286a3 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1249,40 +1249,11 @@
@SystemApi
@RequiresPermission(WRITE_SECURE_SETTINGS)
public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
- final List<String> allProvidersList = getAllProviders();
- // Update all providers on device plus gps and network provider when disabling location.
- Set<String> allProvidersSet = new ArraySet<>(allProvidersList.size() + 2);
- allProvidersSet.addAll(allProvidersList);
- // When disabling location, disable gps and network provider that could have been enabled by
- // location mode api.
- if (enabled == false) {
- allProvidersSet.add(GPS_PROVIDER);
- allProvidersSet.add(NETWORK_PROVIDER);
+ try {
+ mService.setLocationEnabledForUser(enabled, userHandle.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- if (allProvidersSet.isEmpty()) {
- return;
- }
- // 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.
- final String prefix = enabled ? "+" : "-";
- StringBuilder locationProvidersAllowed = new StringBuilder();
- for (String provider : allProvidersSet) {
- checkProvider(provider);
- if (provider.equals(PASSIVE_PROVIDER)) {
- continue;
- }
- locationProvidersAllowed.append(prefix);
- locationProvidersAllowed.append(provider);
- locationProvidersAllowed.append(",");
- }
- // Remove the trailing comma
- locationProvidersAllowed.setLength(locationProvidersAllowed.length() - 1);
- Settings.Secure.putStringForUser(
- mContext.getContentResolver(),
- Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- locationProvidersAllowed.toString(),
- userHandle.getIdentifier());
}
/**
@@ -1295,22 +1266,11 @@
*/
@SystemApi
public boolean isLocationEnabledForUser(UserHandle userHandle) {
- final String allowedProviders = Settings.Secure.getStringForUser(
- mContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
- userHandle.getIdentifier());
- if (allowedProviders == null) {
- return false;
+ try {
+ return mService.isLocationEnabledForUser(userHandle.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- final List<String> providerList = Arrays.asList(allowedProviders.split(","));
- for(String provider : getAllProviders()) {
- if (provider.equals(PASSIVE_PROVIDER)) {
- continue;
- }
- if (providerList.contains(provider)) {
- return true;
- }
- }
- return false;
}
/**
@@ -1362,9 +1322,12 @@
@SystemApi
public boolean isProviderEnabledForUser(String provider, UserHandle userHandle) {
checkProvider(provider);
- String allowedProviders = Settings.Secure.getStringForUser(mContext.getContentResolver(),
- Settings.Secure.LOCATION_PROVIDERS_ALLOWED, userHandle.getIdentifier());
- return TextUtils.delimitedStringContains(allowedProviders, ',', provider);
+
+ try {
+ return mService.isProviderEnabledForUser(provider, userHandle.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
}
/**
@@ -1383,16 +1346,13 @@
public boolean setProviderEnabledForUser(
String provider, boolean enabled, UserHandle userHandle) {
checkProvider(provider);
- // 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;
+
+ try {
+ return mService.setProviderEnabledForUser(
+ provider, enabled, userHandle.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- return Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider, userHandle.getIdentifier());
}
/**
diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_layout_rot90.xml b/packages/SystemUI/res/layout-sw600dp/navigation_layout_rot90.xml
index 6f153c1..78304fd 100644
--- a/packages/SystemUI/res/layout-sw600dp/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout-sw600dp/navigation_layout_rot90.xml
@@ -41,16 +41,4 @@
</FrameLayout>
- <com.android.systemui.statusbar.policy.DeadZone
- android:id="@+id/deadzone"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:layout_gravity="top"
- systemui:minSize="@dimen/navigation_bar_deadzone_size"
- systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
- systemui:holdTime="@integer/navigation_bar_deadzone_hold"
- systemui:decayTime="@integer/navigation_bar_deadzone_decay"
- systemui:orientation="horizontal"
- />
-
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 3e60794..953abc7 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -46,16 +46,4 @@
</com.android.systemui.statusbar.phone.NearestTouchFrame>
- <com.android.systemui.statusbar.policy.DeadZone
- android:id="@+id/deadzone"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:layout_gravity="top"
- systemui:minSize="@dimen/navigation_bar_deadzone_size"
- systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
- systemui:holdTime="@integer/navigation_bar_deadzone_hold"
- systemui:decayTime="@integer/navigation_bar_deadzone_decay"
- systemui:orientation="horizontal"
- />
-
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 39cdff4..0e17e5b5 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -46,16 +46,4 @@
</com.android.systemui.statusbar.phone.NearestTouchFrame>
- <com.android.systemui.statusbar.policy.DeadZone
- android:id="@+id/deadzone"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:layout_gravity="top"
- systemui:minSize="@dimen/navigation_bar_deadzone_size"
- systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
- systemui:holdTime="@integer/navigation_bar_deadzone_hold"
- systemui:decayTime="@integer/navigation_bar_deadzone_decay"
- systemui:orientation="vertical"
- />
-
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index 9d336e2..f0138a6 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -60,7 +60,11 @@
<include layout="@layout/heads_up_status_bar_layout" />
+ <!-- The alpha of the left side is controlled by PhoneStatusBarTransitions, and the
+ individual views are controlled by StatusBarManager disable flags DISABLE_CLOCK and
+ DISABLE_NOTIFICATION_ICONS, respectively -->
<LinearLayout
+ android:id="@+id/status_bar_left_side"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:clipChildren="false"
@@ -76,8 +80,6 @@
android:gravity="center_vertical|start"
/>
- <!-- The alpha of this area is controlled from both PhoneStatusBarTransitions and
- PhoneStatusBar (DISABLE_NOTIFICATION_ICONS). -->
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
android:id="@+id/notification_icon_area"
android:layout_width="0dp"
diff --git a/packages/SystemUI/res/values-land/config.xml b/packages/SystemUI/res/values-land/config.xml
index f7e2344..63bbe62 100644
--- a/packages/SystemUI/res/values-land/config.xml
+++ b/packages/SystemUI/res/values-land/config.xml
@@ -28,4 +28,7 @@
<!-- We have only space for one notification on phone landscape layouts. -->
<integer name="keyguard_max_notification_count">1</integer>
+
+ <!-- orientation of the dead zone when touches have recently occurred elsewhere on screen -->
+ <integer name="navigation_bar_deadzone_orientation">1</integer>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 67dabdb..f91af03 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -35,4 +35,7 @@
<!-- Animation duration when using long press on recents to dock -->
<integer name="long_press_dock_anim_duration">290</integer>
+ <!-- orientation of the dead zone when touches have recently occurred elsewhere on screen -->
+ <integer name="navigation_bar_deadzone_orientation">0</integer>
+
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 711d550..f49d3de4 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -93,6 +93,9 @@
<integer name="navigation_bar_deadzone_hold">333</integer>
<integer name="navigation_bar_deadzone_decay">333</integer>
+ <!-- orientation of the dead zone when touches have recently occurred elsewhere on screen -->
+ <integer name="navigation_bar_deadzone_orientation">0</integer>
+
<bool name="config_dead_zone_flash">false</bool>
<!-- Whether to enable dimming navigation buttons when wallpaper is not visible, should be
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 5a2263c..ae6ee2a 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -73,7 +73,7 @@
void onAppOpChanged(int code, int uid, String packageName, boolean active);
/**
- * Gets active app ops for this user and package.
+ * Gets active app ops for this user and package
*/
@Nullable ArraySet<Integer> getAppOps(int userId, String packageName);
}
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 8cff56d..8e59842 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Handler;
@@ -39,6 +40,7 @@
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.GraphicBufferCompat;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.CallbackController;
@@ -71,11 +73,13 @@
private final DeviceProvisionedController mDeviceProvisionedController
= Dependency.get(DeviceProvisionedController.class);
private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
+ private final Intent mQuickStepIntent;
private IOverviewProxy mOverviewProxy;
private int mConnectionBackoffAttempts;
private CharSequence mOnboardingText;
private @InteractionType int mInteractionFlags;
+ private boolean mIsEnabled;
private ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() {
@@ -130,14 +134,23 @@
});
}
} finally {
+ Prefs.putInt(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS, mInteractionFlags);
Binder.restoreCallingIdentity(token);
}
}
};
- private final BroadcastReceiver mLauncherAddedReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mLauncherStateChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
+ updateEnabledState();
+
+ // When launcher service is disabled, reset interaction flags because it is inactive
+ if (!isEnabled()) {
+ mInteractionFlags = 0;
+ Prefs.remove(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS);
+ }
+
// Reconnect immediately, instead of waiting for resume to arrive.
startConnectionToCurrentUser();
}
@@ -196,17 +209,21 @@
mConnectionBackoffAttempts = 0;
mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
com.android.internal.R.string.config_recentsComponentName));
+ mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
+ .setPackage(mRecentsComponentName.getPackageName());
+ mInteractionFlags = Prefs.getInt(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS, 0);
// Listen for the package update changes.
if (SystemServicesProxy.getInstance(context)
.isSystemUser(mDeviceProvisionedController.getCurrentUser())) {
+ updateEnabledState();
mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback);
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
filter.addDataSchemeSpecificPart(mRecentsComponentName.getPackageName(),
PatternMatcher.PATTERN_LITERAL);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- mContext.registerReceiver(mLauncherAddedReceiver, filter);
+ mContext.registerReceiver(mLauncherStateChangedReceiver, filter);
}
}
@@ -222,7 +239,7 @@
disconnectFromLauncherService();
// If user has not setup yet or already connected, do not try to connect
- if (!mDeviceProvisionedController.isCurrentUserSetup()) {
+ if (!mDeviceProvisionedController.isCurrentUserSetup() || !isEnabled()) {
return;
}
mHandler.removeCallbacks(mConnectionRunnable);
@@ -248,6 +265,7 @@
public void addCallback(OverviewProxyListener listener) {
mConnectionCallbacks.add(listener);
listener.onConnectionChanged(mOverviewProxy != null);
+ listener.onInteractionFlagsChanged(mInteractionFlags);
}
@Override
@@ -256,7 +274,11 @@
}
public boolean shouldShowSwipeUpUI() {
- return getProxy() != null && ((mInteractionFlags & FLAG_DISABLE_SWIPE_UP) == 0);
+ return isEnabled() && ((mInteractionFlags & FLAG_DISABLE_SWIPE_UP) == 0);
+ }
+
+ public boolean isEnabled() {
+ return mIsEnabled;
}
public IOverviewProxy getProxy() {
@@ -292,6 +314,11 @@
}
}
+ private void updateEnabledState() {
+ mIsEnabled = mContext.getPackageManager().resolveServiceAsUser(mQuickStepIntent, 0,
+ ActivityManagerWrapper.getInstance().getCurrentUserId()) != null;
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(TAG_OPS + " state:");
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 2a27147..7f7a769 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -54,7 +54,8 @@
Key.HAS_SEEN_RECENTS_ONBOARDING,
Key.SEEN_RINGER_GUIDANCE_COUNT,
Key.QS_HAS_TURNED_OFF_MOBILE_DATA,
- Key.TOUCHED_RINGER_TOGGLE
+ Key.TOUCHED_RINGER_TOGGLE,
+ Key.QUICK_STEP_INTERACTION_FLAGS
})
public @interface Key {
@Deprecated
@@ -93,6 +94,7 @@
String QS_TILE_SPECS_REVEALED = "QsTileSpecsRevealed";
String QS_HAS_TURNED_OFF_MOBILE_DATA = "QsHasTurnedOffMobileData";
String TOUCHED_RINGER_TOGGLE = "TouchedRingerToggle";
+ String QUICK_STEP_INTERACTION_FLAGS = "QuickStepInteractionFlags";
}
public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java
index e18ac74..cdf4ba7 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java
@@ -16,6 +16,9 @@
package com.android.systemui.classifier;
+import android.os.Build;
+import android.os.SystemProperties;
+import android.util.Log;
import android.view.MotionEvent;
import java.util.ArrayList;
@@ -49,13 +52,18 @@
public class AnglesClassifier extends StrokeClassifier {
private HashMap<Stroke, Data> mStrokeMap = new HashMap<>();
+ public static final boolean VERBOSE = SystemProperties.getBoolean("debug.falsing_log.ang",
+ Build.IS_DEBUGGABLE);
+
+ private static String TAG = "ANG";
+
public AnglesClassifier(ClassifierData classifierData) {
mClassifierData = classifierData;
}
@Override
public String getTag() {
- return "ANG";
+ return TAG;
}
@Override
@@ -170,18 +178,31 @@
public float getAnglesVariance() {
float anglesVariance = getAnglesVariance(mSumSquares, mSum, mCount);
+ if (VERBOSE) {
+ FalsingLog.i(TAG, "getAnglesVariance: (first pass) " + anglesVariance);
+ FalsingLog.i(TAG, " - mFirstLength=" + mFirstLength);
+ FalsingLog.i(TAG, " - mLength=" + mLength);
+ }
if (mFirstLength < mLength / 2f) {
anglesVariance = Math.min(anglesVariance, mFirstAngleVariance
+ getAnglesVariance(mSecondSumSquares, mSecondSum, mSecondCount));
+ if (VERBOSE) FalsingLog.i(TAG, "getAnglesVariance: (second pass) " + anglesVariance);
}
return anglesVariance;
}
public float getAnglesPercentage() {
if (mAnglesCount == 0.0f) {
+ if (VERBOSE) FalsingLog.i(TAG, "getAnglesPercentage: count==0, result=1");
return 1.0f;
}
- return (Math.max(mLeftAngles, mRightAngles) + mStraightAngles) / mAnglesCount;
+ final float result = (Math.max(mLeftAngles, mRightAngles) + mStraightAngles) / mAnglesCount;
+ if (VERBOSE) {
+ FalsingLog.i(TAG, "getAnglesPercentage: left=" + mLeftAngles + " right="
+ + mRightAngles + " straight=" + mStraightAngles + " count=" + mAnglesCount
+ + " result=" + result);
+ }
+ return result;
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java
index 6883dd0..5f6c1b7 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java
@@ -20,8 +20,6 @@
public static float evaluate(float value, int type) {
final boolean secureUnlock = type == Classifier.BOUNCER_UNLOCK;
float evaluation = 0.0f;
- if (value > 0.05) evaluation++;
- if (value > 0.10) evaluation++;
if (value > 0.20) evaluation++;
if (value > 0.40 && !secureUnlock) evaluation++;
if (value > 0.80 && !secureUnlock) evaluation++;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesClassifier.java
index 6df72b1..66f0cf6 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesClassifier.java
@@ -16,6 +16,8 @@
package com.android.systemui.classifier;
+import android.os.Build;
+import android.os.SystemProperties;
import android.view.MotionEvent;
import java.util.ArrayList;
@@ -34,6 +36,10 @@
* should be in this interval.
*/
public class SpeedAnglesClassifier extends StrokeClassifier {
+ public static final boolean VERBOSE = SystemProperties.getBoolean("debug.falsing_log.spd_ang",
+ Build.IS_DEBUGGABLE);
+ public static final String TAG = "SPD_ANG";
+
private HashMap<Stroke, Data> mStrokeMap = new HashMap<>();
public SpeedAnglesClassifier(ClassifierData classifierData) {
@@ -42,7 +48,7 @@
@Override
public String getTag() {
- return "SPD_ANG";
+ return TAG;
}
@Override
@@ -135,14 +141,24 @@
}
public float getAnglesVariance() {
- return mSumSquares / mCount - (mSum / mCount) * (mSum / mCount);
+ final float v = mSumSquares / mCount - (mSum / mCount) * (mSum / mCount);
+ if (VERBOSE) {
+ FalsingLog.i(TAG, "getAnglesVariance: sum^2=" + mSumSquares
+ + " count=" + mCount + " result=" + v);
+ }
+ return v;
}
public float getAnglesPercentage() {
if (mAnglesCount == 0.0f) {
return 1.0f;
}
- return (mAcceleratingAngles) / mAnglesCount;
+ final float v = (mAcceleratingAngles) / mAnglesCount;
+ if (VERBOSE) {
+ FalsingLog.i(TAG, "getAnglesPercentage: angles=" + mAcceleratingAngles
+ + " count=" + mAnglesCount + " result=" + v);
+ }
+ return v;
}
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 3c9dae0..a70b358 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -229,10 +229,11 @@
// Bump the notification when the bucket dropped.
.setWhen(mWarningTriggerTimeMs)
.setShowWhen(false)
- .setContentTitle(title)
.setContentText(contentText)
+ .setContentTitle(title)
.setOnlyAlertOnce(true)
.setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
+ .setStyle(new Notification.BigTextStyle().bigText(contentText))
.setVisibility(Notification.VISIBILITY_PUBLIC);
if (hasBatterySettings()) {
nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
index eb95866..20e3cee 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
@@ -44,4 +44,9 @@
public TextView getAppLabel() {
return mSecondLine;
}
+
+ @Override
+ protected boolean animationsEnabled() {
+ return false;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
index 862a6a4..e7e756f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java
@@ -159,13 +159,13 @@
return getColorForState(getContext(), state);
}
- public static void animateGrayScale(int fromColor, int toColor, ImageView iv,
- final Runnable endRunnable) {
+ private void animateGrayScale(int fromColor, int toColor, ImageView iv,
+ final Runnable endRunnable) {
if (iv instanceof AlphaControlledSlashImageView) {
((AlphaControlledSlashImageView)iv)
.setFinalImageTintList(ColorStateList.valueOf(toColor));
}
- if (ValueAnimator.areAnimatorsEnabled()) {
+ if (mAnimationEnabled && ValueAnimator.areAnimatorsEnabled()) {
final float fromAlpha = Color.alpha(fromColor);
final float toAlpha = Color.alpha(toColor);
final float fromChannel = Color.red(fromColor);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index 09d928f..cc60f87 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -179,7 +179,7 @@
protected void handleStateChanged(QSTile.State state) {
int circleColor = getCircleColor(state.state);
if (circleColor != mCircleColor) {
- if (mBg.isShown()) {
+ if (mBg.isShown() && animationsEnabled()) {
ValueAnimator animator = ValueAnimator.ofArgb(mCircleColor, circleColor)
.setDuration(QS_ANIM_LENGTH);
animator.addUpdateListener(animation -> mBg.setImageTintList(ColorStateList.valueOf(
@@ -205,6 +205,10 @@
}
}
+ protected boolean animationsEnabled() {
+ return true;
+ }
+
private int getCircleColor(int state) {
switch (state) {
case Tile.STATE_ACTIVE:
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 19da3db..6fcb1c1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -126,7 +126,7 @@
@Override
public void onTaskStackChangedBackground() {
// Skip background preloading recents in SystemUI if the overview services is bound
- if (Dependency.get(OverviewProxyService.class).getProxy() != null) {
+ if (Dependency.get(OverviewProxyService.class).isEnabled()) {
return;
}
@@ -300,7 +300,7 @@
public void onBootCompleted() {
// Skip preloading tasks if we are already bound to the service
- if (Dependency.get(OverviewProxyService.class).getProxy() != null) {
+ if (Dependency.get(OverviewProxyService.class).isEnabled()) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java
index 2ec78cf..019c680 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AppOpsListener.java
@@ -62,7 +62,7 @@
public void onOpActiveChanged(int code, int uid, String packageName, boolean active) {
mFsc.onAppOpChanged(code, uid, packageName, active);
mPresenter.getHandler().post(() -> {
- mEntryManager.updateNotificationsForAppOps(code, uid, packageName, active);
+ mEntryManager.updateNotificationsForAppOp(code, uid, packageName, active);
});
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 4b6ab64..ab46b39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -383,8 +383,6 @@
}
mGroupManager.onEntryAdded(entry);
- updateAppOps(entry);
-
updateRankingAndSort(mRankingMap);
}
@@ -403,25 +401,14 @@
updateRankingAndSort(ranking);
}
- private void updateAppOps(Entry entry) {
- final int uid = entry.notification.getUid();
- final String pkg = entry.notification.getPackageName();
- ArraySet<Integer> activeOps = mFsc.getAppOps(entry.notification.getUserId(), pkg);
- if (activeOps != null) {
- int N = activeOps.size();
- for (int i = 0; i < N; i++) {
- updateAppOp(activeOps.valueAt(i), uid, pkg, true);
- }
- }
- }
-
- public void updateAppOp(int appOp, int uid, String pkg, boolean showIcon) {
+ public void updateAppOp(int appOp, int uid, String pkg, String key, boolean showIcon) {
synchronized (mEntries) {
final int N = mEntries.size();
for (int i = 0; i < N; i++) {
Entry entry = mEntries.valueAt(i);
if (uid == entry.notification.getUid()
- && pkg.equals(entry.notification.getPackageName())) {
+ && pkg.equals(entry.notification.getPackageName())
+ && key.equals(entry.key)) {
if (showIcon) {
entry.mActiveAppOps.add(appOp);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
index 45df450..849cfdd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
@@ -43,6 +43,7 @@
import android.view.View;
import android.view.ViewGroup;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.NotificationMessagingUtil;
@@ -665,6 +666,7 @@
}
// Add the expanded view and icon.
mNotificationData.add(entry);
+ tagForeground(entry.notification);
updateNotifications();
}
@@ -726,6 +728,19 @@
mPendingNotifications.put(key, shadeEntry);
}
+ @VisibleForTesting
+ protected void tagForeground(StatusBarNotification notification) {
+ ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps(
+ notification.getUserId(), notification.getPackageName());
+ if (activeOps != null) {
+ int N = activeOps.size();
+ for (int i = 0; i < N; i++) {
+ updateNotificationsForAppOp(activeOps.valueAt(i), notification.getUid(),
+ notification.getPackageName(), true);
+ }
+ }
+ }
+
@Override
public void addNotification(StatusBarNotification notification,
NotificationListenerService.RankingMap ranking) {
@@ -736,10 +751,11 @@
}
}
- public void updateNotificationsForAppOps(int appOp, int uid, String pkg, boolean showIcon) {
- if (mForegroundServiceController.getStandardLayoutKey(
- UserHandle.getUserId(uid), pkg) != null) {
- mNotificationData.updateAppOp(appOp, uid, pkg, showIcon);
+ public void updateNotificationsForAppOp(int appOp, int uid, String pkg, boolean showIcon) {
+ String foregroundKey = mForegroundServiceController.getStandardLayoutKey(
+ UserHandle.getUserId(uid), pkg);
+ if (foregroundKey != null) {
+ mNotificationData.updateAppOp(appOp, uid, pkg, foregroundKey, showIcon);
updateNotifications();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 75b31c5..9fcb090 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -14,6 +14,7 @@
package com.android.systemui.statusbar.phone;
+import static android.app.StatusBarManager.DISABLE_CLOCK;
import static android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS;
import static android.app.StatusBarManager.DISABLE_SYSTEM_INFO;
@@ -96,6 +97,7 @@
mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
mClockView = mStatusBar.findViewById(R.id.clock);
showSystemIconArea(false);
+ showClock(false);
initEmergencyCryptkeeperText();
initOperatorName();
}
@@ -163,6 +165,13 @@
showNotificationIconArea(animate);
}
}
+ if ((diff1 & DISABLE_CLOCK) != 0) {
+ if ((state1 & DISABLE_CLOCK) != 0) {
+ hideClock(animate);
+ } else {
+ showClock(animate);
+ }
+ }
}
protected int adjustDisableFlags(int state) {
@@ -171,6 +180,7 @@
&& shouldHideNotificationIcons()) {
state |= DISABLE_NOTIFICATION_ICONS;
state |= DISABLE_SYSTEM_INFO;
+ state |= DISABLE_CLOCK;
}
if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
if (mNetworkController.hasEmergencyCryptKeeperText()) {
@@ -195,11 +205,17 @@
public void hideSystemIconArea(boolean animate) {
animateHide(mSystemIconArea, animate);
- animateHide(mClockView, animate);
}
public void showSystemIconArea(boolean animate) {
animateShow(mSystemIconArea, animate);
+ }
+
+ public void hideClock(boolean animate) {
+ animateHide(mClockView, animate);
+ }
+
+ public void showClock(boolean animate) {
animateShow(mClockView, animate);
}
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 f216695..4c4eb60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -124,7 +124,7 @@
private TintedKeyButtonDrawable mRotateSuggestionIcon;
private GestureHelper mGestureHelper;
- private DeadZone mDeadZone;
+ private final DeadZone mDeadZone;
private final NavigationBarTransitions mBarTransitions;
private final OverviewProxyService mOverviewProxyService;
@@ -263,6 +263,7 @@
new ButtonDispatcher(R.id.accessibility_button));
mButtonDispatchers.put(R.id.rotate_suggestion,
new ButtonDispatcher(R.id.rotate_suggestion));
+ mDeadZone = new DeadZone(this);
}
public BarTransitions getBarTransitions() {
@@ -297,6 +298,10 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
+ if (mDeadZone.onTouchEvent(event)) {
+ // Consumed the touch event
+ return true;
+ }
switch (event.getActionMasked()) {
case ACTION_DOWN:
int x = (int) event.getX();
@@ -319,6 +324,10 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
+ if (mDeadZone.onTouchEvent(event)) {
+ // Consumed the touch event
+ return true;
+ }
if (mGestureHelper.onTouchEvent(event)) {
return true;
}
@@ -389,7 +398,7 @@
public boolean isQuickScrubEnabled() {
return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", true)
- && mOverviewProxyService.getProxy() != null && isOverviewEnabled()
+ && mOverviewProxyService.isEnabled() && isOverviewEnabled()
&& ((mOverviewProxyService.getInteractionFlags() & FLAG_DISABLE_QUICK_SCRUB) == 0);
}
@@ -587,7 +596,7 @@
// recents buttons when disconnected from launcher service in screen pinning mode,
// as they are used for exiting.
final boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
- if (mOverviewProxyService.getProxy() != null) {
+ if (mOverviewProxyService.isEnabled()) {
// Use interaction flags to show/hide navigation buttons but will be shown if required
// to exit screen pinning.
final int flags = mOverviewProxyService.getInteractionFlags();
@@ -818,6 +827,7 @@
@Override
protected void onDraw(Canvas canvas) {
mGestureHelper.onDraw(canvas);
+ mDeadZone.onDraw(canvas);
super.onDraw(canvas);
}
@@ -889,10 +899,8 @@
public void reorient() {
updateCurrentView();
- mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
-
((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone);
- mDeadZone.setDisplayRotation(mCurrentRotation);
+ mDeadZone.onConfigurationChanged(mCurrentRotation);
// force the low profile & disabled states into compliance
mBarTransitions.init();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
index 12bdfc6..a7d5aca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -43,10 +43,9 @@
}
public void init() {
- mLeftSide = mView.findViewById(R.id.notification_icon_area);
+ mLeftSide = mView.findViewById(R.id.status_bar_left_side);
mStatusIcons = mView.findViewById(R.id.statusIcons);
mBattery = mView.findViewById(R.id.battery);
- mClock = mView.findViewById(R.id.clock);
applyModeBackground(-1, getMode(), false /*animate*/);
applyMode(getMode(), false /*animate*/);
}
@@ -89,8 +88,7 @@
anims.playTogether(
animateTransitionTo(mLeftSide, newAlpha),
animateTransitionTo(mStatusIcons, newAlpha),
- animateTransitionTo(mBattery, newAlphaBC),
- animateTransitionTo(mClock, newAlphaBC)
+ animateTransitionTo(mBattery, newAlphaBC)
);
if (isLightsOut(mode)) {
anims.setDuration(LIGHTS_OUT_DURATION);
@@ -101,7 +99,6 @@
mLeftSide.setAlpha(newAlpha);
mStatusIcons.setAlpha(newAlpha);
mBattery.setAlpha(newAlphaBC);
- mClock.setAlpha(newAlphaBC);
}
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index a51cd93..af77804 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -168,8 +168,8 @@
}
private boolean handleTouchEvent(MotionEvent event) {
- if (!mNavigationBarView.isQuickScrubEnabled()
- && !mNavigationBarView.isQuickStepSwipeUpEnabled()) {
+ if (mOverviewEventSender.getProxy() == null || (!mNavigationBarView.isQuickScrubEnabled()
+ && !mNavigationBarView.isQuickStepSwipeUpEnabled())) {
mNavigationBarView.getHomeButton().setDelayTouchFeedback(false /* delay */);
return false;
}
@@ -199,7 +199,7 @@
break;
}
case MotionEvent.ACTION_MOVE: {
- if (mQuickStepStarted || !mAllowGestureDetection){
+ if (mQuickStepStarted || !mAllowGestureDetection || mHomeButtonView == null){
break;
}
int x = (int) event.getX();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 2c025b5..28f3162 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -807,7 +807,7 @@
@VisibleForTesting
protected WakeLock createWakeLock() {
return new DelayedWakeLock(getHandler(),
- WakeLock.createPartial(mContext, "Doze"));
+ WakeLock.createPartial(mContext, "Scrims"));
}
@Override
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 750d2a5..f7a97be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1425,11 +1425,15 @@
}
public void addQsTile(ComponentName tile) {
- mQSPanel.getHost().addTile(tile);
+ if (mQSPanel.getHost() != null) {
+ mQSPanel.getHost().addTile(tile);
+ }
}
public void remQsTile(ComponentName tile) {
- mQSPanel.getHost().removeTile(tile);
+ if (mQSPanel.getHost() != null) {
+ mQSPanel.getHost().removeTile(tile);
+ }
}
public void clickTile(ComponentName tile) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
index 06040e2..4a11754 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -17,18 +17,16 @@
package com.android.systemui.statusbar.policy;
import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.TypedArray;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.os.SystemClock;
-import android.util.AttributeSet;
import android.util.Slog;
import android.view.MotionEvent;
import android.view.Surface;
-import android.view.View;
import com.android.systemui.R;
import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.statusbar.phone.NavigationBarView;
import com.android.systemui.statusbar.phone.StatusBar;
/**
@@ -38,7 +36,7 @@
* outside the navigation bar (since this is when accidental taps are more likely), then contracts
* back over time (since a later tap might be intended for the top of the bar).
*/
-public class DeadZone extends View {
+public class DeadZone {
public static final String TAG = "DeadZone";
public static final boolean DEBUG = false;
@@ -47,6 +45,7 @@
private static final boolean CHATTY = true; // print to logcat when we eat a click
private final StatusBar mStatusBar;
+ private final NavigationBarView mNavigationBarView;
private boolean mShouldFlash;
private float mFlashFrac = 0f;
@@ -67,31 +66,11 @@
}
};
- public DeadZone(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public DeadZone(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DeadZone,
- defStyle, 0);
-
- mHold = a.getInteger(R.styleable.DeadZone_holdTime, 0);
- mDecay = a.getInteger(R.styleable.DeadZone_decayTime, 0);
-
- mSizeMin = a.getDimensionPixelSize(R.styleable.DeadZone_minSize, 0);
- mSizeMax = a.getDimensionPixelSize(R.styleable.DeadZone_maxSize, 0);
-
- int index = a.getInt(R.styleable.DeadZone_orientation, -1);
- mVertical = (index == VERTICAL);
-
- if (DEBUG)
- Slog.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
- + (mVertical ? " vertical" : " horizontal"));
-
- setFlashOnTouchCapture(context.getResources().getBoolean(R.bool.config_dead_zone_flash));
- mStatusBar = SysUiServiceProvider.getComponent(context, StatusBar.class);
+ public DeadZone(NavigationBarView view) {
+ mNavigationBarView = view;
+ mStatusBar = SysUiServiceProvider.getComponent(mNavigationBarView.getContext(),
+ StatusBar.class);
+ onConfigurationChanged(HORIZONTAL);
}
static float lerp(float a, float b, float f) {
@@ -112,11 +91,29 @@
public void setFlashOnTouchCapture(boolean dbg) {
mShouldFlash = dbg;
mFlashFrac = 0f;
- postInvalidate();
+ mNavigationBarView.postInvalidate();
+ }
+
+ public void onConfigurationChanged(int rotation) {
+ mDisplayRotation = rotation;
+
+ final Resources res = mNavigationBarView.getResources();
+ mHold = res.getInteger(R.integer.navigation_bar_deadzone_hold);
+ mDecay = res.getInteger(R.integer.navigation_bar_deadzone_decay);
+
+ mSizeMin = res.getDimensionPixelSize(R.dimen.navigation_bar_deadzone_size);
+ mSizeMax = res.getDimensionPixelSize(R.dimen.navigation_bar_deadzone_size_max);
+ int index = res.getInteger(R.integer.navigation_bar_deadzone_orientation);
+ mVertical = (index == VERTICAL);
+
+ if (DEBUG) {
+ Slog.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
+ + (mVertical ? " vertical" : " horizontal"));
+ }
+ setFlashOnTouchCapture(res.getBoolean(R.bool.config_dead_zone_flash));
}
// I made you a touch event...
- @Override
public boolean onTouchEvent(MotionEvent event) {
if (DEBUG) {
Slog.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
@@ -143,7 +140,7 @@
final boolean consumeEvent;
if (mVertical) {
if (mDisplayRotation == Surface.ROTATION_270) {
- consumeEvent = event.getX() > getWidth() - size;
+ consumeEvent = event.getX() > mNavigationBarView.getWidth() - size;
} else {
consumeEvent = event.getX() < size;
}
@@ -155,8 +152,8 @@
Slog.v(TAG, "consuming errant click: (" + event.getX() + "," + event.getY() + ")");
}
if (mShouldFlash) {
- post(mDebugFlash);
- postInvalidate();
+ mNavigationBarView.post(mDebugFlash);
+ mNavigationBarView.postInvalidate();
}
return true; // ...but I eated it
}
@@ -168,19 +165,18 @@
mLastPokeTime = event.getEventTime();
if (DEBUG)
Slog.v(TAG, "poked! size=" + getSize(mLastPokeTime));
- if (mShouldFlash) postInvalidate();
+ if (mShouldFlash) mNavigationBarView.postInvalidate();
}
public void setFlash(float f) {
mFlashFrac = f;
- postInvalidate();
+ mNavigationBarView.postInvalidate();
}
public float getFlash() {
return mFlashFrac;
}
- @Override
public void onDraw(Canvas can) {
if (!mShouldFlash || mFlashFrac <= 0f) {
return;
@@ -202,10 +198,6 @@
if (DEBUG && size > mSizeMin)
// crazy aggressive redrawing here, for debugging only
- postInvalidateDelayed(100);
- }
-
- public void setDisplayRotation(int rotation) {
- mDisplayRotation = rotation;
+ mNavigationBarView.postInvalidateDelayed(100);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 5d7e938..44c2757 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -200,7 +200,7 @@
}
public boolean onTouchEvent(MotionEvent ev) {
- final boolean isProxyConnected = mOverviewProxyService.getProxy() != null;
+ final boolean showSwipeUI = mOverviewProxyService.shouldShowSwipeUpUI();
final int action = ev.getAction();
int x, y;
if (action == MotionEvent.ACTION_DOWN) {
@@ -226,7 +226,7 @@
// Provide the same haptic feedback that the system offers for virtual keys.
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
- if (!isProxyConnected) {
+ if (!showSwipeUI) {
playSoundEffect(SoundEffectConstants.CLICK);
}
removeCallbacks(mCheckLongPress);
@@ -255,7 +255,7 @@
final boolean doIt = isPressed() && !mLongClicked;
setPressed(false);
final boolean doHapticFeedback = (SystemClock.uptimeMillis() - mDownTime) > 150;
- if (isProxyConnected) {
+ if (showSwipeUI) {
if (doIt) {
if (doHapticFeedback) {
mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
index 5ec3dff..e1814098 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/DelayedWakeLock.java
@@ -23,7 +23,7 @@
*/
public class DelayedWakeLock implements WakeLock {
- private static final long RELEASE_DELAY_MS = 120;
+ private static final long RELEASE_DELAY_MS = 240;
private final Handler mHandler;
private final WakeLock mInner;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
index 2a48c4b..dc0e2b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AppOpsListenerTest.java
@@ -86,7 +86,7 @@
mListener.onOpActiveChanged(
AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
waitForIdleSync(mHandler);
- verify(mEntryManager, times(1)).updateNotificationsForAppOps(
+ verify(mEntryManager, times(1)).updateNotificationsForAppOp(
AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
index 5e27fde..5ec77ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationDataTest.java
@@ -139,32 +139,7 @@
Assert.assertTrue(mRow.getEntry().channel != null);
}
- @Test
- public void testAdd_appOpsAdded() {
- ArraySet<Integer> expected = new ArraySet<>();
- expected.add(3);
- expected.add(235);
- expected.add(1);
- when(mFsc.getAppOps(mRow.getEntry().notification.getUserId(),
- mRow.getEntry().notification.getPackageName())).thenReturn(expected);
- mNotificationData.add(mRow.getEntry());
- assertEquals(expected.size(),
- mNotificationData.get(mRow.getEntry().key).mActiveAppOps.size());
- for (int op : expected) {
- assertTrue(" entry missing op " + op,
- mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(op));
- }
- }
-
- @Test
- public void testAdd_noExistingAppOps() {
- when(mFsc.getAppOps(mRow.getEntry().notification.getUserId(),
- mRow.getEntry().notification.getPackageName())).thenReturn(null);
-
- mNotificationData.add(mRow.getEntry());
- assertEquals(0, mNotificationData.get(mRow.getEntry().key).mActiveAppOps.size());
- }
@Test
public void testAllRelevantNotisTaggedWithAppOps() throws Exception {
@@ -181,7 +156,9 @@
for (int op : expectedOps) {
mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
- NotificationTestHelper.PKG, true);
+ NotificationTestHelper.PKG, mRow.getEntry().key, true);
+ mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
+ NotificationTestHelper.PKG, row2.getEntry().key, true);
}
for (int op : expectedOps) {
assertTrue(mRow.getEntry().key + " doesn't have op " + op,
@@ -205,12 +182,12 @@
for (int op : expectedOps) {
mNotificationData.updateAppOp(op, NotificationTestHelper.UID,
- NotificationTestHelper.PKG, true);
+ NotificationTestHelper.PKG, row2.getEntry().key, true);
}
expectedOps.remove(OP_ACCEPT_HANDOVER);
mNotificationData.updateAppOp(OP_ACCEPT_HANDOVER, NotificationTestHelper.UID,
- NotificationTestHelper.PKG, false);
+ NotificationTestHelper.PKG, row2.getEntry().key, false);
assertTrue(mRow.getEntry().key + " doesn't have op " + OP_CAMERA,
mNotificationData.get(mRow.getEntry().key).mActiveAppOps.contains(OP_CAMERA));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
index 3703d6a..7cfd7a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationEntryManagerTest.java
@@ -37,18 +37,15 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationRankingUpdate;
import android.service.notification.StatusBarNotification;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.util.ArraySet;
import android.widget.FrameLayout;
import com.android.internal.logging.MetricsLogger;
@@ -56,12 +53,13 @@
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.UiOffloadThread;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
+import junit.framework.Assert;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -285,13 +283,12 @@
com.android.systemui.util.Assert.isNotMainThread();
when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
- .thenReturn("something");
+ .thenReturn(mEntry.key);
mEntry.row = mRow;
mEntryManager.getNotificationData().add(mEntry);
-
mHandler.post(() -> {
- mEntryManager.updateNotificationsForAppOps(
+ mEntryManager.updateNotificationsForAppOp(
AppOpsManager.OP_CAMERA, mEntry.notification.getUid(),
mEntry.notification.getPackageName(), true);
});
@@ -309,10 +306,65 @@
when(mForegroundServiceController.getStandardLayoutKey(anyInt(), anyString()))
.thenReturn(null);
mHandler.post(() -> {
- mEntryManager.updateNotificationsForAppOps(AppOpsManager.OP_CAMERA, 1000, "pkg", true);
+ mEntryManager.updateNotificationsForAppOp(AppOpsManager.OP_CAMERA, 1000, "pkg", true);
});
waitForIdleSync(mHandler);
verify(mPresenter, never()).updateNotificationViews();
}
+
+ @Test
+ public void testAddNotificationExistingAppOps() {
+ mEntry.row = mRow;
+ mEntryManager.getNotificationData().add(mEntry);
+ ArraySet<Integer> expected = new ArraySet<>();
+ expected.add(3);
+ expected.add(235);
+ expected.add(1);
+
+ when(mForegroundServiceController.getAppOps(mEntry.notification.getUserId(),
+ mEntry.notification.getPackageName())).thenReturn(expected);
+ when(mForegroundServiceController.getStandardLayoutKey(
+ mEntry.notification.getUserId(),
+ mEntry.notification.getPackageName())).thenReturn(mEntry.key);
+
+ mEntryManager.tagForeground(mEntry.notification);
+
+ Assert.assertEquals(expected.size(), mEntry.mActiveAppOps.size());
+ for (int op : expected) {
+ assertTrue("Entry missing op " + op, mEntry.mActiveAppOps.contains(op));
+ }
+ }
+
+ @Test
+ public void testAdd_noExistingAppOps() {
+ mEntry.row = mRow;
+ mEntryManager.getNotificationData().add(mEntry);
+ when(mForegroundServiceController.getStandardLayoutKey(
+ mEntry.notification.getUserId(),
+ mEntry.notification.getPackageName())).thenReturn(mEntry.key);
+ when(mForegroundServiceController.getAppOps(mEntry.notification.getUserId(),
+ mEntry.notification.getPackageName())).thenReturn(null);
+
+ mEntryManager.tagForeground(mEntry.notification);
+ Assert.assertEquals(0, mEntry.mActiveAppOps.size());
+ }
+
+ @Test
+ public void testAdd_existingAppOpsNotForegroundNoti() {
+ mEntry.row = mRow;
+ mEntryManager.getNotificationData().add(mEntry);
+ ArraySet<Integer> ops = new ArraySet<>();
+ ops.add(3);
+ ops.add(235);
+ ops.add(1);
+ when(mForegroundServiceController.getAppOps(mEntry.notification.getUserId(),
+ mEntry.notification.getPackageName())).thenReturn(ops);
+ when(mForegroundServiceController.getStandardLayoutKey(
+ mEntry.notification.getUserId(),
+ mEntry.notification.getPackageName())).thenReturn("something else");
+
+ mEntryManager.tagForeground(mEntry.notification);
+ Assert.assertEquals(0, mEntry.mActiveAppOps.size());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
index 2edcd01..9e8fa22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
@@ -89,15 +89,11 @@
assertEquals(View.INVISIBLE, mFragment.getView().findViewById(R.id.system_icon_area)
.getVisibility());
- assertEquals(View.INVISIBLE, mFragment.getView().findViewById(R.id.clock)
- .getVisibility());
fragment.disable(0, 0, false);
assertEquals(View.VISIBLE, mFragment.getView().findViewById(R.id.system_icon_area)
.getVisibility());
- assertEquals(View.VISIBLE, mFragment.getView().findViewById(R.id.clock)
- .getVisibility());
}
@Test
@@ -115,4 +111,20 @@
Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.VISIBLE));
}
+
+ @Test
+ public void testDisableClock() throws Exception {
+ mFragments.dispatchResume();
+ processAllMessages();
+
+ CollapsedStatusBarFragment fragment = (CollapsedStatusBarFragment) mFragment;
+ fragment.initNotificationIconArea(mMockNotificiationAreaController);
+ fragment.disable(StatusBarManager.DISABLE_CLOCK, 0, false);
+
+ assertEquals(View.INVISIBLE, mFragment.getView().findViewById(R.id.clock).getVisibility());
+
+ fragment.disable(0, 0, false);
+
+ assertEquals(View.VISIBLE, mFragment.getView().findViewById(R.id.clock).getVisibility());
+ }
}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index c6878d7..c66c7b0 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5562,6 +5562,16 @@
// OS: P
PREVIOUSLY_CONNECTED_DEVICES = 1370;
+ // ACTION: A Settings Slice is requested
+ // CATEGORY: SETTINGS
+ // OS: P
+ ACTION_SETTINGS_SLICE_REQUESTED = 1371;
+
+ // ACTION: A Settings Slice is updated with new value
+ // CATEGORY: SETTINGS
+ // OS: P
+ ACTION_SETTINGS_SLICE_CHANGED = 1372;
+
// ---- End P Constants, all P constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index bde6bd8..cd90e3f 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -24,6 +24,8 @@
import static android.system.OsConstants.SOCK_DGRAM;
import static com.android.internal.util.Preconditions.checkNotNull;
+import android.annotation.NonNull;
+import android.app.AppOpsManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.IIpSecService;
@@ -42,6 +44,7 @@
import android.net.TrafficStats;
import android.net.util.NetdService;
import android.os.Binder;
+import android.os.DeadSystemException;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -974,6 +977,13 @@
return service;
}
+ @NonNull
+ private AppOpsManager getAppOpsManager() {
+ AppOpsManager appOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
+ if(appOps == null) throw new RuntimeException("System Server couldn't get AppOps");
+ return appOps;
+ }
+
/** @hide */
@VisibleForTesting
public IpSecService(Context context, IpSecServiceConfiguration config) {
@@ -1240,7 +1250,9 @@
*/
@Override
public synchronized IpSecTunnelInterfaceResponse createTunnelInterface(
- String localAddr, String remoteAddr, Network underlyingNetwork, IBinder binder) {
+ String localAddr, String remoteAddr, Network underlyingNetwork, IBinder binder,
+ String callingPackage) {
+ enforceTunnelPermissions(callingPackage);
checkNotNull(binder, "Null Binder passed to createTunnelInterface");
checkNotNull(underlyingNetwork, "No underlying network was specified");
checkInetAddress(localAddr);
@@ -1320,8 +1332,8 @@
*/
@Override
public synchronized void addAddressToTunnelInterface(
- int tunnelResourceId, LinkAddress localAddr) {
- enforceNetworkStackPermission();
+ int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
+ enforceTunnelPermissions(callingPackage);
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
// Get tunnelInterface record; if no such interface is found, will throw
@@ -1352,10 +1364,10 @@
*/
@Override
public synchronized void removeAddressFromTunnelInterface(
- int tunnelResourceId, LinkAddress localAddr) {
- enforceNetworkStackPermission();
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+ int tunnelResourceId, LinkAddress localAddr, String callingPackage) {
+ enforceTunnelPermissions(callingPackage);
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
// Get tunnelInterface record; if no such interface is found, will throw
// IllegalArgumentException
TunnelInterfaceRecord tunnelInterfaceInfo =
@@ -1383,7 +1395,9 @@
* server
*/
@Override
- public synchronized void deleteTunnelInterface(int resourceId) throws RemoteException {
+ public synchronized void deleteTunnelInterface(
+ int resourceId, String callingPackage) throws RemoteException {
+ enforceTunnelPermissions(callingPackage);
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
releaseResource(userRecord.mTunnelInterfaceRecords, resourceId);
}
@@ -1469,7 +1483,6 @@
case IpSecTransform.MODE_TRANSPORT:
break;
case IpSecTransform.MODE_TUNNEL:
- enforceNetworkStackPermission();
break;
default:
throw new IllegalArgumentException(
@@ -1477,9 +1490,20 @@
}
}
- private void enforceNetworkStackPermission() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_STACK,
- "IpSecService");
+ private void enforceTunnelPermissions(String callingPackage) {
+ checkNotNull(callingPackage, "Null calling package cannot create IpSec tunnels");
+ switch (getAppOpsManager().noteOp(
+ AppOpsManager.OP_MANAGE_IPSEC_TUNNELS,
+ Binder.getCallingUid(), callingPackage)) {
+ case AppOpsManager.MODE_DEFAULT:
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_IPSEC_TUNNELS, "IpSecService");
+ break;
+ case AppOpsManager.MODE_ALLOWED:
+ return;
+ default:
+ throw new SecurityException("Request to ignore AppOps for non-legacy API");
+ }
}
private void createOrUpdateTransform(
@@ -1535,8 +1559,12 @@
* result in all of those sockets becoming unable to send or receive data.
*/
@Override
- public synchronized IpSecTransformResponse createTransform(IpSecConfig c, IBinder binder)
- throws RemoteException {
+ public synchronized IpSecTransformResponse createTransform(
+ IpSecConfig c, IBinder binder, String callingPackage) throws RemoteException {
+ checkNotNull(c);
+ if (c.getMode() == IpSecTransform.MODE_TUNNEL) {
+ enforceTunnelPermissions(callingPackage);
+ }
checkIpSecConfig(c);
checkNotNull(binder, "Null Binder passed to createTransform");
final int resourceId = mNextResourceId++;
@@ -1657,8 +1685,9 @@
*/
@Override
public synchronized void applyTunnelModeTransform(
- int tunnelResourceId, int direction, int transformResourceId) throws RemoteException {
- enforceNetworkStackPermission();
+ int tunnelResourceId, int direction,
+ int transformResourceId, String callingPackage) throws RemoteException {
+ enforceTunnelPermissions(callingPackage);
checkDirection(direction);
UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 26b83f5..fb5fba0 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -1344,13 +1344,7 @@
* @param provider the name of the location provider
*/
private boolean isAllowedByCurrentUserSettingsLocked(String provider) {
- if (mEnabledProviders.contains(provider)) {
- return true;
- }
- if (mDisabledProviders.contains(provider)) {
- return false;
- }
- return isLocationProviderEnabledForUser(provider, mCurrentUserId);
+ return isAllowedByUserSettingsLockedForUser(provider, mCurrentUserId);
}
/**
@@ -1359,13 +1353,33 @@
* 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 isAllowedByUserSettingsLocked(String provider, int uid) {
+ private boolean isAllowedByUserSettingsLockedForUser(String provider, int userId) {
+ if (mEnabledProviders.contains(provider)) {
+ return true;
+ }
+ if (mDisabledProviders.contains(provider)) {
+ return false;
+ }
+ return isLocationProviderEnabledForUser(provider, userId);
+ }
+
+
+ /**
+ * 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 isAllowedByUserSettingsLocked(String provider, int uid, int userId) {
if (!isCurrentProfile(UserHandle.getUserId(uid)) && !isUidALocationProvider(uid)) {
return false;
}
- return isAllowedByCurrentUserSettingsLocked(provider);
+ return isAllowedByUserSettingsLockedForUser(provider, userId);
}
/**
@@ -1572,7 +1586,8 @@
continue;
}
if (allowedResolutionLevel >= getMinimumResolutionLevelForProviderUse(name)) {
- if (enabledOnly && !isAllowedByUserSettingsLocked(name, uid)) {
+ if (enabledOnly
+ && !isAllowedByUserSettingsLocked(name, uid, mCurrentUserId)) {
continue;
}
if (criteria != null && !LocationProvider.propertiesMeetCriteria(
@@ -2098,7 +2113,7 @@
oldRecord.disposeLocked(false);
}
- boolean isProviderEnabled = isAllowedByUserSettingsLocked(name, uid);
+ boolean isProviderEnabled = isAllowedByUserSettingsLocked(name, uid, mCurrentUserId);
if (isProviderEnabled) {
applyRequirementsLocked(name);
} else {
@@ -2219,7 +2234,7 @@
LocationProviderInterface provider = mProvidersByName.get(name);
if (provider == null) return null;
- if (!isAllowedByUserSettingsLocked(name, uid)) return null;
+ if (!isAllowedByUserSettingsLocked(name, uid, mCurrentUserId)) return null;
Location location;
if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) {
@@ -2540,6 +2555,173 @@
}
/**
+ * Returns the current location enabled/disabled status for a user
+ *
+ * @param userId the id of the user
+ * @return true if location is enabled
+ */
+ @Override
+ public boolean isLocationEnabledForUser(int userId) {
+ // Check INTERACT_ACROSS_USERS permission if userId is not current user id.
+ checkInteractAcrossUsersPermission(userId);
+
+ long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ final String allowedProviders = Settings.Secure.getStringForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
+ userId);
+ if (allowedProviders == null) {
+ return false;
+ }
+ final List<String> providerList = Arrays.asList(allowedProviders.split(","));
+ for(String provider : mRealProviders.keySet()) {
+ if (provider.equals(LocationManager.PASSIVE_PROVIDER)
+ || provider.equals(LocationManager.FUSED_PROVIDER)) {
+ continue;
+ }
+ if (providerList.contains(provider)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Enable or disable location for a user
+ *
+ * @param enabled true to enable location, false to disable location
+ * @param userId the id of the user
+ */
+ @Override
+ public void setLocationEnabledForUser(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);
+
+ long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ final Set<String> allRealProviders = mRealProviders.keySet();
+ // Update all providers on device plus gps and network provider when disabling
+ // location
+ Set<String> allProvidersSet = new ArraySet<>(allRealProviders.size() + 2);
+ allProvidersSet.addAll(allRealProviders);
+ // When disabling location, disable gps and network provider that could have been
+ // enabled by location mode api.
+ if (enabled == false) {
+ allProvidersSet.add(LocationManager.GPS_PROVIDER);
+ allProvidersSet.add(LocationManager.NETWORK_PROVIDER);
+ }
+ if (allProvidersSet.isEmpty()) {
+ return;
+ }
+ // 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.
+ final String prefix = enabled ? "+" : "-";
+ StringBuilder locationProvidersAllowed = new StringBuilder();
+ for (String provider : allProvidersSet) {
+ if (provider.equals(LocationManager.PASSIVE_PROVIDER)
+ || provider.equals(LocationManager.FUSED_PROVIDER)) {
+ continue;
+ }
+ locationProvidersAllowed.append(prefix);
+ locationProvidersAllowed.append(provider);
+ locationProvidersAllowed.append(",");
+ }
+ // Remove the trailing comma
+ locationProvidersAllowed.setLength(locationProvidersAllowed.length() - 1);
+ Settings.Secure.putStringForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
+ locationProvidersAllowed.toString(),
+ userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Returns the current enabled/disabled status of a location provider and user
+ *
+ * @param provider name of the provider
+ * @param userId the id of the user
+ * @return true if the provider exists and 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();
+ synchronized (mLock) {
+ LocationProviderInterface p = mProvidersByName.get(provider);
+ return p != null
+ && isAllowedByUserSettingsLocked(provider, uid, userId);
+ }
+ }
+
+ /**
+ * Enable or disable a single location provider.
+ *
+ * @param provider name of the provider
+ * @param enabled true to enable the provider. False to disable the provider
+ * @param userId the id of the user to set
+ * @return true if the value was set, false on errors
+ */
+ @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);
+
+ // 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;
+
+ long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ // No such provider exists
+ if (!mProvidersByName.containsKey(provider)) return false;
+
+ // If it is a test provider, do not write to Settings.Secure
+ if (mMockProviders.containsKey(provider)) {
+ setTestProviderEnabled(provider, enabled);
+ return true;
+ }
+
+ // 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.
+ String providerChange = (enabled ? "+" : "-") + provider;
+ return Settings.Secure.putStringForUser(
+ mContext.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
+ providerChange, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
* Read location provider status from Settings.Secure
*
* @param provider the location provider to query
@@ -2560,6 +2742,23 @@
}
/**
+ * 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
@@ -3076,7 +3275,11 @@
if (!canCallerAccessMockLocation(opPackageName)) {
return;
}
+ setTestProviderEnabled(provider, enabled);
+ }
+ /** Enable or disable a test location provider. */
+ private void setTestProviderEnabled(String provider, boolean enabled) {
synchronized (mLock) {
MockProvider mockProvider = mMockProviders.get(provider);
if (mockProvider == null) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index c8b6b50..3e82c25 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -320,13 +320,13 @@
0, // STREAM_SYSTEM
0, // STREAM_RING
0, // STREAM_MUSIC
- 0, // STREAM_ALARM
+ 1, // STREAM_ALARM
0, // STREAM_NOTIFICATION
0, // STREAM_BLUETOOTH_SCO
0, // STREAM_SYSTEM_ENFORCED
0, // STREAM_DTMF
0, // STREAM_TTS
- 0 // STREAM_ACCESSIBILITY
+ 1 // STREAM_ACCESSIBILITY
};
/* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings
@@ -1208,6 +1208,8 @@
System.VOLUME_SETTINGS_INT[a11yStreamAlias];
mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].setAllIndexes(
mStreamStates[a11yStreamAlias], caller);
+ mStreamStates[AudioSystem.STREAM_ACCESSIBILITY].refreshRange(
+ mStreamVolumeAlias[AudioSystem.STREAM_ACCESSIBILITY]);
}
}
if (sIndependentA11yVolume) {
@@ -1389,7 +1391,15 @@
}
private int rescaleIndex(int index, int srcStream, int dstStream) {
- return (index * mStreamStates[dstStream].getMaxIndex() + mStreamStates[srcStream].getMaxIndex() / 2) / mStreamStates[srcStream].getMaxIndex();
+ final int rescaled =
+ (index * mStreamStates[dstStream].getMaxIndex()
+ + mStreamStates[srcStream].getMaxIndex() / 2)
+ / mStreamStates[srcStream].getMaxIndex();
+ if (rescaled < mStreamStates[dstStream].getMinIndex()) {
+ return mStreamStates[dstStream].getMinIndex();
+ } else {
+ return rescaled;
+ }
}
///////////////////////////////////////////////////////////////////////////
@@ -4602,8 +4612,8 @@
// 4 VolumeStreamState.class
public class VolumeStreamState {
private final int mStreamType;
- private final int mIndexMin;
- private final int mIndexMax;
+ private int mIndexMin;
+ private int mIndexMax;
private boolean mIsMuted;
private String mVolumeIndexSettingName;
@@ -4889,6 +4899,24 @@
}
/**
+ * Updates the min/max index values from another stream. Use this when changing the alias
+ * for the current stream type.
+ * @param sourceStreamType
+ */
+ // must be sync'd on mSettingsLock before VolumeStreamState.class
+ @GuardedBy("VolumeStreamState.class")
+ public void refreshRange(int sourceStreamType) {
+ mIndexMin = MIN_STREAM_VOLUME[sourceStreamType] * 10;
+ mIndexMax = MAX_STREAM_VOLUME[sourceStreamType] * 10;
+ // verify all current volumes are within bounds
+ for (int i = 0 ; i < mIndexMap.size(); i++) {
+ final int device = mIndexMap.keyAt(i);
+ final int index = mIndexMap.valueAt(i);
+ mIndexMap.put(device, getValidIndex(index));
+ }
+ }
+
+ /**
* Copies all device/index pairs from the given VolumeStreamState after initializing
* them with the volume for DEVICE_OUT_DEFAULT. No-op if the source VolumeStreamState
* has the same stream type as this instance.
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 88df195..905c7e3 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -686,10 +686,15 @@
}
public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats(int userId) {
- ArrayList<AmbientBrightnessDayStats> stats = mAmbientBrightnessStatsTracker.getUserStats(
- userId);
- return (stats != null) ? new ParceledListSlice<>(stats) : new ParceledListSlice<>(
- Collections.EMPTY_LIST);
+ if (mAmbientBrightnessStatsTracker != null) {
+ ArrayList<AmbientBrightnessDayStats> stats =
+ mAmbientBrightnessStatsTracker.getUserStats(
+ userId);
+ if (stats != null) {
+ return new ParceledListSlice<>(stats);
+ }
+ }
+ return ParceledListSlice.emptyList();
}
// Not allowed to keep the SensorEvent so used to copy the data we care about.
diff --git a/services/core/java/com/android/server/input/InputWindowHandle.java b/services/core/java/com/android/server/input/InputWindowHandle.java
index 3d6f7ad..720eaaa5 100644
--- a/services/core/java/com/android/server/input/InputWindowHandle.java
+++ b/services/core/java/com/android/server/input/InputWindowHandle.java
@@ -92,7 +92,7 @@
public int inputFeatures;
// Display this input is on.
- public final int displayId;
+ public int displayId;
private native void nativeDispose();
diff --git a/services/core/java/com/android/server/net/watchlist/ReportEncoder.java b/services/core/java/com/android/server/net/watchlist/ReportEncoder.java
index 2a8f4d5..a482e05 100644
--- a/services/core/java/com/android/server/net/watchlist/ReportEncoder.java
+++ b/services/core/java/com/android/server/net/watchlist/ReportEncoder.java
@@ -49,6 +49,7 @@
* Apply DP on watchlist results, and generate a serialized watchlist report ready to store
* in DropBox.
*/
+ @Nullable
static byte[] encodeWatchlistReport(WatchlistConfig config, byte[] userSecret,
List<String> appDigestList, WatchlistReportDbHelper.AggregatedResult aggregatedResult) {
Map<String, Boolean> resultMap = PrivacyUtils.createDpEncodedReportMap(
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistConfig.java b/services/core/java/com/android/server/net/watchlist/WatchlistConfig.java
index d793842..8352ca6 100644
--- a/services/core/java/com/android/server/net/watchlist/WatchlistConfig.java
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistConfig.java
@@ -16,6 +16,7 @@
package com.android.server.net.watchlist;
+import android.annotation.Nullable;
import android.os.FileUtils;
import android.util.AtomicFile;
import android.util.Log;
@@ -55,9 +56,6 @@
private static final String NETWORK_WATCHLIST_DB_FOR_TEST_PATH =
"/data/misc/network_watchlist/network_watchlist_for_test.xml";
- // Hash for null / unknown config, a 32 byte array filled with content 0x00
- private static final byte[] UNKNOWN_CONFIG_HASH = new byte[32];
-
private static class XmlTags {
private static final String WATCHLIST_CONFIG = "watchlist-config";
private static final String SHA256_DOMAIN = "sha256-domain";
@@ -228,16 +226,21 @@
return mIsSecureConfig;
}
+ @Nullable
+ /**
+ * Get watchlist config SHA-256 digest.
+ * Return null if watchlist config does not exist.
+ */
public byte[] getWatchlistConfigHash() {
if (!mXmlFile.exists()) {
- return UNKNOWN_CONFIG_HASH;
+ return null;
}
try {
return DigestUtils.getSha256Hash(mXmlFile);
} catch (IOException | NoSuchAlgorithmException e) {
Log.e(TAG, "Unable to get watchlist config hash", e);
}
- return UNKNOWN_CONFIG_HASH;
+ return null;
}
/**
@@ -271,8 +274,10 @@
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("Watchlist config hash: " + HexDump.toHexString(getWatchlistConfigHash()));
+ final byte[] hash = getWatchlistConfigHash();
+ pw.println("Watchlist config hash: " + (hash != null ? HexDump.toHexString(hash) : null));
pw.println("Domain CRC32 digest list:");
+ // mDomainDigests won't go from non-null to null so it's safe
if (mDomainDigests != null) {
mDomainDigests.crc32Digests.dump(fd, pw, args);
}
@@ -281,6 +286,7 @@
mDomainDigests.sha256Digests.dump(fd, pw, args);
}
pw.println("Ip CRC32 digest list:");
+ // mIpDigests won't go from non-null to null so it's safe
if (mIpDigests != null) {
mIpDigests.crc32Digests.dump(fd, pw, args);
}
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java b/services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java
index b331b9c..864ce5d 100644
--- a/services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistLoggingHandler.java
@@ -346,6 +346,7 @@
* @param ipAddresses Ip address that you want to search in watchlist.
* @return Ip address that exists in watchlist, null if it does not match anything.
*/
+ @Nullable
private String searchIpInWatchlist(String[] ipAddresses) {
for (String ipAddress : ipAddresses) {
if (isIpInWatchlist(ipAddress)) {
@@ -377,6 +378,7 @@
* @param host Host that we want to search.
* @return Domain that exists in watchlist, null if it does not match anything.
*/
+ @Nullable
private String searchAllSubDomainsInWatchlist(String host) {
if (host == null) {
return null;
@@ -392,6 +394,7 @@
/** Get all sub-domains in a host */
@VisibleForTesting
+ @Nullable
static String[] getAllSubDomains(String host) {
if (host == null) {
return null;
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistReportDbHelper.java b/services/core/java/com/android/server/net/watchlist/WatchlistReportDbHelper.java
index 632ab81..c69934a 100644
--- a/services/core/java/com/android/server/net/watchlist/WatchlistReportDbHelper.java
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistReportDbHelper.java
@@ -144,6 +144,7 @@
* Aggregate all records in database before input timestamp, and return a
* rappor encoded result.
*/
+ @Nullable
public AggregatedResult getAggregatedRecords(long untilTimestamp) {
final String selectStatement = WhiteListReportContract.TIMESTAMP + " < ?";
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
index e20a510..c2f3ba0 100644
--- a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
@@ -86,7 +86,7 @@
}
}
- public void reloadSettings() {
+ private void reloadSettings() {
if (!mXmlFile.exists()) {
// No settings config
return;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f31ca0a..899d271 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2286,6 +2286,12 @@
}
@Override
+ public int getBlockedChannelCount(String pkg, int uid) {
+ enforceSystemOrSystemUI("getBlockedChannelCount");
+ return mRankingHelper.getBlockedChannelCount(pkg, uid);
+ }
+
+ @Override
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroupsForPackage(
String pkg, int uid, boolean includeDeleted) {
checkCallerIsSystem();
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 98d5c9a..43d393a 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -15,6 +15,8 @@
*/
package com.android.server.notification;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
@@ -619,7 +621,7 @@
updateConfig();
return;
}
- if (channel.getImportance() < NotificationManager.IMPORTANCE_NONE
+ if (channel.getImportance() < IMPORTANCE_NONE
|| channel.getImportance() > NotificationManager.IMPORTANCE_MAX) {
throw new IllegalArgumentException("Invalid importance level");
}
@@ -959,6 +961,23 @@
return deletedCount;
}
+ public int getBlockedChannelCount(String pkg, int uid) {
+ Preconditions.checkNotNull(pkg);
+ int blockedCount = 0;
+ Record r = getRecord(pkg, uid);
+ if (r == null) {
+ return blockedCount;
+ }
+ int N = r.channels.size();
+ for (int i = 0; i < N; i++) {
+ final NotificationChannel nc = r.channels.valueAt(i);
+ if (!nc.isDeleted() && IMPORTANCE_NONE == nc.getImportance()) {
+ blockedCount++;
+ }
+ }
+ return blockedCount;
+ }
+
/**
* Sets importance.
*/
@@ -969,12 +988,12 @@
}
public void setEnabled(String packageName, int uid, boolean enabled) {
- boolean wasEnabled = getImportance(packageName, uid) != NotificationManager.IMPORTANCE_NONE;
+ boolean wasEnabled = getImportance(packageName, uid) != IMPORTANCE_NONE;
if (wasEnabled == enabled) {
return;
}
setImportance(packageName, uid,
- enabled ? DEFAULT_IMPORTANCE : NotificationManager.IMPORTANCE_NONE);
+ enabled ? DEFAULT_IMPORTANCE : IMPORTANCE_NONE);
}
@VisibleForTesting
@@ -1199,7 +1218,7 @@
ArrayMap<Integer, String> packageBans = new ArrayMap<>(N);
for (int i = 0; i < N; i++) {
final Record r = mRecords.valueAt(i);
- if (r.importance == NotificationManager.IMPORTANCE_NONE) {
+ if (r.importance == IMPORTANCE_NONE) {
packageBans.put(r.uid, r.pkg);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2e530af..0e0bfbd 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17,12 +17,12 @@
package com.android.server.pm;
import static android.Manifest.permission.DELETE_PACKAGES;
-import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
-import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
import static android.Manifest.permission.INSTALL_PACKAGES;
+import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
+import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
@@ -167,8 +167,8 @@
import android.content.pm.PackageInstaller;
import android.content.pm.PackageList;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackageListObserver;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.ActivityIntentInfo;
@@ -310,10 +310,10 @@
import com.android.server.pm.dex.PackageDexUsage;
import com.android.server.pm.permission.BasePermission;
import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
-import com.android.server.pm.permission.PermissionManagerService;
-import com.android.server.pm.permission.PermissionManagerInternal;
import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
+import com.android.server.pm.permission.PermissionManagerInternal;
import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
+import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionsState;
import com.android.server.pm.permission.PermissionsState.PermissionState;
import com.android.server.security.VerityUtils;
@@ -8185,35 +8185,22 @@
private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForComponent(flags, userId, name);
- final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
- // reader
+ final int callingUid = Binder.getCallingUid();
synchronized (mPackages) {
final PackageParser.Provider provider = mProvidersByAuthority.get(name);
PackageSetting ps = provider != null
? mSettings.mPackages.get(provider.owner.packageName)
: null;
if (ps != null) {
- final boolean isInstantApp = ps.getInstantApp(userId);
- // normal application; filter out instant application provider
- if (instantAppPkgName == null && isInstantApp) {
- return null;
- }
- // instant application; filter out other instant applications
- if (instantAppPkgName != null
- && isInstantApp
- && !provider.owner.packageName.equals(instantAppPkgName)) {
- return null;
- }
- // instant application; filter out non-exposed provider
- if (instantAppPkgName != null
- && !isInstantApp
- && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
- return null;
- }
// provider not enabled
if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
return null;
}
+ final ComponentName component =
+ new ComponentName(provider.info.packageName, provider.info.name);
+ if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
+ return null;
+ }
return PackageParser.generateProviderInfo(
provider, flags, ps.readUserState(userId), userId);
}
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index fae0b24..d4625e9 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -379,7 +379,7 @@
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG)
- Slog.d(TAG, "Time to poll something.");
+ Slog.d(TAG, "Time to trigger periodic alarm.");
synchronized (sStatsdLock) {
if (sStatsd == null) {
Slog.w(TAG, "Could not access statsd to inform it of periodic alarm firing.");
@@ -455,13 +455,13 @@
public void setAlarmForSubscriberTriggering(long timestampMs) {
enforceCallingPermission();
if (DEBUG)
- Slog.d(TAG, "Setting periodic alarm at " + timestampMs);
+ Slog.d(TAG, "Setting periodic alarm in about " +
+ (timestampMs - SystemClock.elapsedRealtime()));
final long callingToken = Binder.clearCallingIdentity();
try {
// using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
// only fire when it awakens.
- // This alarm is inexact, leaving its exactness completely up to the OS optimizations.
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, timestampMs, mPeriodicAlarmIntent);
+ mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, mPeriodicAlarmIntent);
} finally {
Binder.restoreCallingIdentity(callingToken);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 54c2e9b..f015889 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -178,6 +178,7 @@
import android.util.Slog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
+import android.view.Display;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Gravity;
@@ -1366,6 +1367,7 @@
// Window was not laid out for this display yet, so make sure mLayoutSeq does not match.
if (dc != null) {
mLayoutSeq = dc.mLayoutSeq - 1;
+ mInputWindowHandle.displayId = dc.getDisplayId();
}
}
@@ -1378,7 +1380,7 @@
public int getDisplayId() {
final DisplayContent displayContent = getDisplayContent();
if (displayContent == null) {
- return -1;
+ return Display.INVALID_DISPLAY;
}
return displayContent.getDisplayId();
}
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index 92cc537..45bee6e 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -30,9 +30,11 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ParceledListSlice;
import android.database.ContentObserver;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
+import android.hardware.display.AmbientBrightnessDayStats;
import android.hardware.display.BrightnessChangeEvent;
import android.os.BatteryManager;
import android.os.Handler;
@@ -571,6 +573,19 @@
assertEquals(event.batteryLevel, event2.batteryLevel, FLOAT_DELTA);
}
+ @Test
+ public void testNonNullAmbientStats() {
+ // getAmbientBrightnessStats should return an empty list rather than null when
+ // tracker isn't started or hasn't collected any data.
+ ParceledListSlice<AmbientBrightnessDayStats> slice = mTracker.getAmbientBrightnessStats(0);
+ assertNotNull(slice);
+ assertTrue(slice.getList().isEmpty());
+ startTracker(mTracker);
+ slice = mTracker.getAmbientBrightnessStats(0);
+ assertNotNull(slice);
+ assertTrue(slice.getList().isEmpty());
+ }
+
private InputStream getInputStream(String data) {
return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
}
diff --git a/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistConfigTests.java b/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistConfigTests.java
index 654acc2..678f018 100644
--- a/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistConfigTests.java
+++ b/services/tests/servicestests/src/com/android/server/net/watchlist/WatchlistConfigTests.java
@@ -19,6 +19,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
@@ -114,13 +115,19 @@
}
@Test
- public void testWatchlistConfig_getWatchlistConfigHash() throws Exception {
+ public void testWatchlistConfig_getWatchlistConfigHash_hasConfig() throws Exception {
copyWatchlistConfigXml(mContext, TEST_XML_1, mTestXmlFile);
WatchlistConfig config = new WatchlistConfig(mTestXmlFile);
assertEquals(TEST_XML_1_HASH, HexDump.toHexString(config.getWatchlistConfigHash()));
}
@Test
+ public void testWatchlistConfig_getWatchlistConfigHash_withoutConfig() throws Exception {
+ WatchlistConfig config = new WatchlistConfig(mTestXmlFile);
+ assertNull(config.getWatchlistConfigHash());
+ }
+
+ @Test
public void testWatchlistConfig_testDumpDoesNotCrash() throws Exception {
WatchlistConfig config = new WatchlistConfig(new File("/not_exist_path.xml"));
ByteArrayOutputStream bs = new ByteArrayOutputStream(2048);
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 1248eae..7c928c9 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -326,6 +326,17 @@
assertThat(app.mLayoutSeq, not(is(mDisplayContent.mLayoutSeq)));
}
+ @Test
+ public void testDisplayIdUpdatedOnReparent() throws Exception {
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+ // fake a different display
+ app.mInputWindowHandle.displayId = mDisplayContent.getDisplayId() + 1;
+ app.onDisplayChanged(mDisplayContent);
+
+ assertThat(app.mInputWindowHandle.displayId, is(mDisplayContent.getDisplayId()));
+ assertThat(app.getDisplayId(), is(mDisplayContent.getDisplayId()));
+ }
+
private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
reset(mPowerManagerWrapper);
final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 0815876..54ed1e6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -1093,7 +1093,7 @@
NotificationChannel channel2 =
new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
NotificationChannel channel3 =
- new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
+ new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_HIGH);
mHelper.createNotificationChannel(PKG, UID, channel, true, false);
mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
@@ -1106,6 +1106,24 @@
}
@Test
+ public void testGetBlockedChannelCount() throws Exception {
+ NotificationChannel channel =
+ new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
+ NotificationChannel channel2 =
+ new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_NONE);
+ NotificationChannel channel3 =
+ new NotificationChannel("id5", "a", NotificationManager.IMPORTANCE_NONE);
+ mHelper.createNotificationChannel(PKG, UID, channel, true, false);
+ mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
+ mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
+
+ mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
+
+ assertEquals(1, mHelper.getBlockedChannelCount(PKG, UID));
+ assertEquals(0, mHelper.getBlockedChannelCount("pkg2", UID2));
+ }
+
+ @Test
public void testCreateDeletedChannel() throws Exception {
long[] vibration = new long[]{100, 67, 145, 156};
NotificationChannel channel =
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 36333e4..3bf951d 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -2600,7 +2600,6 @@
}
/**
- *
* Request audio routing to a specific bluetooth device. Calling this method may result in
* the device routing audio to a different bluetooth device than the one specified if the
* bluetooth stack is unable to route audio to the requested device.
@@ -2611,13 +2610,13 @@
* Used by self-managed {@link ConnectionService}s which wish to use bluetooth audio for a
* self-managed {@link Connection} (see {@link PhoneAccount#CAPABILITY_SELF_MANAGED}.)
* <p>
- * See also {@link InCallService#requestBluetoothAudio(String)}
- * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
- * {@link BluetoothDevice#getAddress()}.
+ * See also {@link InCallService#requestBluetoothAudio(BluetoothDevice)}
+ * @param bluetoothDevice The bluetooth device to connect to.
*/
- public void requestBluetoothAudio(@NonNull String bluetoothAddress) {
+ public void requestBluetoothAudio(@NonNull BluetoothDevice bluetoothDevice) {
for (Listener l : mListeners) {
- l.onAudioRouteChanged(this, CallAudioState.ROUTE_BLUETOOTH, bluetoothAddress);
+ l.onAudioRouteChanged(this, CallAudioState.ROUTE_BLUETOOTH,
+ bluetoothDevice.getAddress());
}
}
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index af65c65..bd25ab2 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -428,12 +428,11 @@
* A list of available devices can be obtained via
* {@link CallAudioState#getSupportedBluetoothDevices()}
*
- * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
- * {@link BluetoothDevice#getAddress()}.
+ * @param bluetoothDevice The bluetooth device to connect to.
*/
- public final void requestBluetoothAudio(@NonNull String bluetoothAddress) {
+ public final void requestBluetoothAudio(@NonNull BluetoothDevice bluetoothDevice) {
if (mPhone != null) {
- mPhone.requestBluetoothAudio(bluetoothAddress);
+ mPhone.requestBluetoothAudio(bluetoothDevice.getAddress());
}
}
diff --git a/tests/net/java/android/net/IpSecManagerTest.java b/tests/net/java/android/net/IpSecManagerTest.java
index 970596d..a946e50 100644
--- a/tests/net/java/android/net/IpSecManagerTest.java
+++ b/tests/net/java/android/net/IpSecManagerTest.java
@@ -30,6 +30,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.test.mock.MockContext;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.system.Os;
@@ -69,11 +70,17 @@
private IpSecService mMockIpSecService;
private IpSecManager mIpSecManager;
+ private MockContext mMockContext = new MockContext() {
+ @Override
+ public String getOpPackageName() {
+ return "fooPackage";
+ }
+ };
@Before
public void setUp() throws Exception {
mMockIpSecService = mock(IpSecService.class);
- mIpSecManager = new IpSecManager(mMockIpSecService);
+ mIpSecManager = new IpSecManager(mMockContext, mMockIpSecService);
}
/*
@@ -227,7 +234,7 @@
new IpSecTunnelInterfaceResponse(IpSecManager.Status.OK, resourceId, intfName);
when(mMockIpSecService.createTunnelInterface(
eq(VTI_LOCAL_ADDRESS.getHostAddress()), eq(GOOGLE_DNS_4.getHostAddress()),
- anyObject(), anyObject()))
+ anyObject(), anyObject(), anyString()))
.thenReturn(dummyResponse);
IpSecManager.IpSecTunnelInterface tunnelIntf = mIpSecManager.createIpSecTunnelInterface(
@@ -245,7 +252,7 @@
assertEquals(VTI_INTF_NAME, tunnelIntf.getInterfaceName());
tunnelIntf.close();
- verify(mMockIpSecService).deleteTunnelInterface(eq(DUMMY_RESOURCE_ID));
+ verify(mMockIpSecService).deleteTunnelInterface(eq(DUMMY_RESOURCE_ID), anyString());
}
@Test
@@ -255,10 +262,12 @@
tunnelIntf.addAddress(VTI_INNER_ADDRESS);
verify(mMockIpSecService)
- .addAddressToTunnelInterface(eq(DUMMY_RESOURCE_ID), eq(VTI_INNER_ADDRESS));
+ .addAddressToTunnelInterface(
+ eq(DUMMY_RESOURCE_ID), eq(VTI_INNER_ADDRESS), anyString());
tunnelIntf.removeAddress(VTI_INNER_ADDRESS);
verify(mMockIpSecService)
- .addAddressToTunnelInterface(eq(DUMMY_RESOURCE_ID), eq(VTI_INNER_ADDRESS));
+ .addAddressToTunnelInterface(
+ eq(DUMMY_RESOURCE_ID), eq(VTI_INNER_ADDRESS), anyString());
}
-}
\ No newline at end of file
+}
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 410f754..e573d35 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.AppOpsManager;
import android.content.Context;
import android.net.INetd;
import android.net.IpSecAlgorithm;
@@ -40,6 +41,7 @@
import android.net.NetworkUtils;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
+import android.test.mock.MockContext;
import android.support.test.filters.SmallTest;
import android.system.Os;
@@ -92,7 +94,28 @@
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F
};
- Context mMockContext;
+ AppOpsManager mMockAppOps = mock(AppOpsManager.class);
+
+ MockContext mMockContext = new MockContext() {
+ @Override
+ public Object getSystemService(String name) {
+ switch(name) {
+ case Context.APP_OPS_SERVICE:
+ return mMockAppOps;
+ default:
+ return null;
+ }
+ }
+
+ @Override
+ public void enforceCallingOrSelfPermission(String permission, String message) {
+ if (permission == android.Manifest.permission.MANAGE_IPSEC_TUNNELS) {
+ return;
+ }
+ throw new SecurityException("Unavailable permission requested");
+ }
+ };
+
INetd mMockNetd;
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
@@ -114,13 +137,22 @@
@Before
public void setUp() throws Exception {
- mMockContext = mock(Context.class);
mMockNetd = mock(INetd.class);
mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
// Injecting mock netd
when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
+ // A package granted the AppOp for MANAGE_IPSEC_TUNNELS will be MODE_ALLOWED.
+ when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("blessedPackage")))
+ .thenReturn(AppOpsManager.MODE_ALLOWED);
+ // A system package will not be granted the app op, so this should fall back to
+ // a permissions check, which should pass.
+ when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("systemPackage")))
+ .thenReturn(AppOpsManager.MODE_DEFAULT);
+ // A mismatch between the package name and the UID will return MODE_IGNORED.
+ when(mMockAppOps.noteOp(anyInt(), anyInt(), eq("badPackage")))
+ .thenReturn(AppOpsManager.MODE_IGNORED);
}
@Test
@@ -232,7 +264,7 @@
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
verify(mMockNetd)
@@ -267,7 +299,7 @@
ipSecConfig.setAuthenticatedEncryption(AEAD_ALGO);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
verify(mMockNetd)
@@ -301,12 +333,12 @@
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
assertEquals(IpSecManager.Status.OK, createTransformResp.status);
// Attempting to create transform a second time with the same SPIs should throw an error...
try {
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
fail("IpSecService should have thrown an error for reuse of SPI");
} catch (IllegalStateException expected) {
}
@@ -314,7 +346,7 @@
// ... even if the transform is deleted
mIpSecService.deleteTransform(createTransformResp.resourceId);
try {
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
fail("IpSecService should have thrown an error for reuse of SPI");
} catch (IllegalStateException expected) {
}
@@ -327,7 +359,7 @@
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
IpSecService.UserRecord userRecord =
mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
@@ -351,7 +383,7 @@
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
mIpSecService.deleteTransform(createTransformResp.resourceId);
verify(mMockNetd, times(1))
@@ -398,7 +430,7 @@
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
IpSecService.UserRecord userRecord =
mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
@@ -435,7 +467,7 @@
addAuthAndCryptToIpSecConfig(ipSecConfig);
IpSecTransformResponse createTransformResp =
- mIpSecService.createTransform(ipSecConfig, new Binder());
+ mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
int resourceId = createTransformResp.resourceId;
@@ -460,10 +492,10 @@
}
private IpSecTunnelInterfaceResponse createAndValidateTunnel(
- String localAddr, String remoteAddr) {
+ String localAddr, String remoteAddr, String pkgName) {
IpSecTunnelInterfaceResponse createTunnelResp =
mIpSecService.createTunnelInterface(
- mSourceAddr, mDestinationAddr, fakeNetwork, new Binder());
+ mSourceAddr, mDestinationAddr, fakeNetwork, new Binder(), pkgName);
assertNotNull(createTunnelResp);
assertEquals(IpSecManager.Status.OK, createTunnelResp.status);
@@ -473,7 +505,7 @@
@Test
public void testCreateTunnelInterface() throws Exception {
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr);
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
// Check that we have stored the tracking object, and retrieve it
IpSecService.UserRecord userRecord =
@@ -495,12 +527,12 @@
@Test
public void testDeleteTunnelInterface() throws Exception {
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr);
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
IpSecService.UserRecord userRecord =
mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
- mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId);
+ mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, "blessedPackage");
// Verify quota and RefcountedResource objects cleaned up
assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
@@ -516,7 +548,7 @@
@Test
public void testTunnelInterfaceBinderDeath() throws Exception {
IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr);
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
IpSecService.UserRecord userRecord =
mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
@@ -539,22 +571,34 @@
@Test
public void testAddRemoveAddressFromTunnelInterface() throws Exception {
- IpSecTunnelInterfaceResponse createTunnelResp =
- createAndValidateTunnel(mSourceAddr, mDestinationAddr);
+ for (String pkgName : new String[]{"blessedPackage", "systemPackage"}) {
+ IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, pkgName);
+ mIpSecService.addAddressToTunnelInterface(
+ createTunnelResp.resourceId, mLocalInnerAddress, pkgName);
+ verify(mMockNetd, times(1))
+ .interfaceAddAddress(
+ eq(createTunnelResp.interfaceName),
+ eq(mLocalInnerAddress.getAddress().getHostAddress()),
+ eq(mLocalInnerAddress.getPrefixLength()));
+ mIpSecService.removeAddressFromTunnelInterface(
+ createTunnelResp.resourceId, mLocalInnerAddress, pkgName);
+ verify(mMockNetd, times(1))
+ .interfaceDelAddress(
+ eq(createTunnelResp.interfaceName),
+ eq(mLocalInnerAddress.getAddress().getHostAddress()),
+ eq(mLocalInnerAddress.getPrefixLength()));
+ mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, pkgName);
+ }
+ }
- mIpSecService.addAddressToTunnelInterface(createTunnelResp.resourceId, mLocalInnerAddress);
- verify(mMockNetd)
- .interfaceAddAddress(
- eq(createTunnelResp.interfaceName),
- eq(mLocalInnerAddress.getAddress().getHostAddress()),
- eq(mLocalInnerAddress.getPrefixLength()));
-
- mIpSecService.removeAddressFromTunnelInterface(
- createTunnelResp.resourceId, mLocalInnerAddress);
- verify(mMockNetd)
- .interfaceDelAddress(
- eq(createTunnelResp.interfaceName),
- eq(mLocalInnerAddress.getAddress().getHostAddress()),
- eq(mLocalInnerAddress.getPrefixLength()));
+ @Test
+ public void testAddTunnelFailsForBadPackageName() throws Exception {
+ try {
+ IpSecTunnelInterfaceResponse createTunnelResp =
+ createAndValidateTunnel(mSourceAddr, mDestinationAddr, "badPackage");
+ fail("Expected a SecurityException for badPackage.");
+ } catch (SecurityException expected) {
+ }
}
}