Merge "Fix the logic of parsing profilebootclasspath flags."
diff --git a/GAME_MANAGER_OWNERS b/GAME_MANAGER_OWNERS
index 502a9e36..b65c43a 100644
--- a/GAME_MANAGER_OWNERS
+++ b/GAME_MANAGER_OWNERS
@@ -1,2 +1,3 @@
lpy@google.com
-timvp@google.com
+chingtangyu@google.com
+xwxw@google.com
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
index b6361ce..80a70a6 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java
@@ -31,6 +31,7 @@
import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.expresslog.Counter;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateControllerProto;
@@ -88,6 +89,8 @@
// will never be unsatisfied (our time base can not go backwards).
final long nowElapsedMillis = sElapsedRealtimeClock.millis();
if (job.hasDeadlineConstraint() && evaluateDeadlineConstraint(job, nowElapsedMillis)) {
+ // We're intentionally excluding jobs whose deadlines have passed
+ // (mostly like deadlines of 0) when the job was scheduled.
return;
} else if (job.hasTimingDelayConstraint() && evaluateTimingDelayConstraint(job,
nowElapsedMillis)) {
@@ -159,6 +162,8 @@
// Scheduler.
mStateChangedListener.onRunJobNow(job);
}
+ Counter.logIncrement(
+ "job_scheduler.value_job_scheduler_job_deadline_expired_counter");
} else if (wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) {
// This job's deadline is earlier than the current set alarm. Update the alarm.
setDeadlineExpiredAlarmLocked(job.getLatestRunTimeElapsed(),
@@ -229,6 +234,8 @@
// Scheduler.
mStateChangedListener.onRunJobNow(job);
}
+ Counter.logIncrement(
+ "job_scheduler.value_job_scheduler_job_deadline_expired_counter");
it.remove();
} else { // Sorted by expiry time, so take the next one and stop.
if (!wouldBeReadyWithConstraintLocked(job, JobStatus.CONSTRAINT_DEADLINE)) {
diff --git a/core/api/current.txt b/core/api/current.txt
index ffecc09..6f683295 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -41323,7 +41323,7 @@
field public static final String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
field public static final String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
field public static final String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
- field public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
+ field @Deprecated public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
field public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
field public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
field public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL = "hide_lte_plus_data_icon_bool";
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
index c0aebee..7bfb1b5 100644
--- a/core/java/android/app/AutomaticZenRule.java
+++ b/core/java/android/app/AutomaticZenRule.java
@@ -48,6 +48,13 @@
private String mPkg;
/**
+ * The maximum string length for any string contained in this automatic zen rule. This pertains
+ * both to fields in the rule itself (such as its name) and items with sub-fields.
+ * @hide
+ */
+ public static final int MAX_STRING_LENGTH = 1000;
+
+ /**
* Creates an automatic zen rule.
*
* @param name The name of the rule.
@@ -93,10 +100,10 @@
public AutomaticZenRule(@NonNull String name, @Nullable ComponentName owner,
@Nullable ComponentName configurationActivity, @NonNull Uri conditionId,
@Nullable ZenPolicy policy, int interruptionFilter, boolean enabled) {
- this.name = name;
- this.owner = owner;
- this.configurationActivity = configurationActivity;
- this.conditionId = conditionId;
+ this.name = getTrimmedString(name);
+ this.owner = getTrimmedComponentName(owner);
+ this.configurationActivity = getTrimmedComponentName(configurationActivity);
+ this.conditionId = getTrimmedUri(conditionId);
this.interruptionFilter = interruptionFilter;
this.enabled = enabled;
this.mZenPolicy = policy;
@@ -115,12 +122,14 @@
public AutomaticZenRule(Parcel source) {
enabled = source.readInt() == ENABLED;
if (source.readInt() == ENABLED) {
- name = source.readString();
+ name = getTrimmedString(source.readString());
}
interruptionFilter = source.readInt();
- conditionId = source.readParcelable(null, android.net.Uri.class);
- owner = source.readParcelable(null, android.content.ComponentName.class);
- configurationActivity = source.readParcelable(null, android.content.ComponentName.class);
+ conditionId = getTrimmedUri(source.readParcelable(null, android.net.Uri.class));
+ owner = getTrimmedComponentName(
+ source.readParcelable(null, android.content.ComponentName.class));
+ configurationActivity = getTrimmedComponentName(
+ source.readParcelable(null, android.content.ComponentName.class));
creationTime = source.readLong();
mZenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class);
mModified = source.readInt() == ENABLED;
@@ -196,7 +205,7 @@
* Sets the representation of the state that causes this rule to become active.
*/
public void setConditionId(Uri conditionId) {
- this.conditionId = conditionId;
+ this.conditionId = getTrimmedUri(conditionId);
}
/**
@@ -211,7 +220,7 @@
* Sets the name of this rule.
*/
public void setName(String name) {
- this.name = name;
+ this.name = getTrimmedString(name);
}
/**
@@ -243,7 +252,7 @@
* that are not backed by {@link android.service.notification.ConditionProviderService}.
*/
public void setConfigurationActivity(@Nullable ComponentName componentName) {
- this.configurationActivity = componentName;
+ this.configurationActivity = getTrimmedComponentName(componentName);
}
/**
@@ -333,4 +342,35 @@
return new AutomaticZenRule[size];
}
};
+
+ /**
+ * If the package or class name of the provided ComponentName are longer than MAX_STRING_LENGTH,
+ * return a trimmed version that truncates each of the package and class name at the max length.
+ */
+ private static ComponentName getTrimmedComponentName(ComponentName cn) {
+ if (cn == null) return null;
+ return new ComponentName(getTrimmedString(cn.getPackageName()),
+ getTrimmedString(cn.getClassName()));
+ }
+
+ /**
+ * Returns a truncated copy of the string if the string is longer than MAX_STRING_LENGTH.
+ */
+ private static String getTrimmedString(String input) {
+ if (input != null && input.length() > MAX_STRING_LENGTH) {
+ return input.substring(0, MAX_STRING_LENGTH);
+ }
+ return input;
+ }
+
+ /**
+ * Returns a truncated copy of the Uri by trimming the string representation to the maximum
+ * string length.
+ */
+ private static Uri getTrimmedUri(Uri input) {
+ if (input != null && input.toString().length() > MAX_STRING_LENGTH) {
+ return Uri.parse(getTrimmedString(input.toString()));
+ }
+ return input;
+ }
}
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index f3fc468..8ec313ec 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -11,6 +11,7 @@
per-file ApplicationThreadConstants.java = file:/services/core/java/com/android/server/am/OWNERS
per-file BroadcastOptions.java = file:/services/core/java/com/android/server/am/OWNERS
per-file ContentProviderHolder* = file:/services/core/java/com/android/server/am/OWNERS
+per-file ForegroundService* = file:/services/core/java/com/android/server/am/OWNERS
per-file IActivityController.aidl = file:/services/core/java/com/android/server/am/OWNERS
per-file IActivityManager.aidl = file:/services/core/java/com/android/server/am/OWNERS
per-file IApplicationThread.aidl = file:/services/core/java/com/android/server/am/OWNERS
@@ -29,10 +30,12 @@
per-file Service* = file:/services/core/java/com/android/server/am/OWNERS
per-file SystemServiceRegistry.java = file:/services/core/java/com/android/server/am/OWNERS
per-file *UserSwitchObserver* = file:/services/core/java/com/android/server/am/OWNERS
-per-file UiAutomation* = file:/services/accessibility/OWNERS
+per-file *UiAutomation* = file:/services/accessibility/OWNERS
per-file GameManager* = file:/GAME_MANAGER_OWNERS
+per-file GameMode* = file:/GAME_MANAGER_OWNERS
per-file GameState* = file:/GAME_MANAGER_OWNERS
per-file IGameManager* = file:/GAME_MANAGER_OWNERS
+per-file IGameMode* = file:/GAME_MANAGER_OWNERS
# ActivityThread
per-file ActivityThread.java = file:/services/core/java/com/android/server/am/OWNERS
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 0418a4b..b599028 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -438,8 +438,11 @@
map.ensureCapacity(count);
}
try {
+ // recycleParcel being false implies that we do not own the parcel. In this case, do
+ // not use lazy values to be safe, as the parcel could be recycled outside of our
+ // control.
recycleParcel &= parcelledData.readArrayMap(map, count, !parcelledByNative,
- /* lazy */ true, mClassLoader);
+ /* lazy */ recycleParcel, mClassLoader);
} catch (BadParcelableException e) {
if (sShouldDefuse) {
Log.w(TAG, "Failed to parse Bundle, but defusing quietly", e);
@@ -1845,7 +1848,6 @@
// bundle immediately; neither of which is obvious.
synchronized (this) {
initializeFromParcelLocked(parcel, /*recycleParcel=*/ false, isNativeBundle);
- unparcel(/* itemwise */ true);
}
return;
}
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 6d5c741..3d10661 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -911,11 +911,15 @@
final String transactionName = getTransactionName(transactionCode);
final StringBuffer buf = new StringBuffer();
+ // Keep trace name consistent with cpp trace name in:
+ // system/tools/aidl/generate_cpp.cpp
+ buf.append("AIDL::java::");
if (transactionName != null) {
- buf.append(mSimpleDescriptor).append(":").append(transactionName);
+ buf.append(mSimpleDescriptor).append("::").append(transactionName);
} else {
- buf.append(mSimpleDescriptor).append("#").append(transactionCode);
+ buf.append(mSimpleDescriptor).append("::#").append(transactionCode);
}
+ buf.append("::server");
transactionTraceName = buf.toString();
mTransactionTraceNames.setRelease(index, transactionTraceName);
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 6330661..1929a4d 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -536,8 +536,8 @@
mWarnOnBlocking = false;
warnOnBlocking = false;
- if (Build.IS_USERDEBUG) {
- // Log this as a WTF on userdebug builds.
+ if (Build.IS_USERDEBUG || Build.IS_ENG) {
+ // Log this as a WTF on userdebug and eng builds.
Log.wtf(Binder.TAG,
"Outgoing transactions from this process must be FLAG_ONEWAY",
new Throwable());
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 9d8df7e..1924dc6 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -73,4 +73,3 @@
# PermissionEnforcer
per-file PermissionEnforcer.java = tweek@google.com, brufino@google.com
-per-file PermissionEnforcer.java = file:/core/java/android/permission/OWNERS
diff --git a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
index c8c1fd4..eb467e0 100644
--- a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
+++ b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java
@@ -93,8 +93,9 @@
* associated with each signer.
*
* @throws SignatureNotFoundException if the APK is not signed using APK Signature Scheme v2.
- * @throws SecurityException if a APK Signature Scheme v2 signature of this APK does not verify.
- * @throws IOException if an I/O error occurs while reading the APK file.
+ * @throws SecurityException if an APK Signature Scheme v2 signature of this APK does
+ * not verify.
+ * @throws IOException if an I/O error occurs while reading the APK file.
*/
public static X509Certificate[][] verify(String apkFile)
throws SignatureNotFoundException, SecurityException, IOException {
@@ -386,7 +387,6 @@
break;
}
}
- return;
}
static byte[] getVerityRootHash(String apkPath)
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 9f88f33..01837f4 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -25,6 +25,7 @@
#include <inttypes.h>
#include <mutex>
#include <stdio.h>
+#include <string>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -880,7 +881,7 @@
case FAILED_TRANSACTION: {
ALOGE("!!! FAILED BINDER TRANSACTION !!! (parcel size = %d)", parcelSize);
const char* exceptionToThrow;
- char msg[128];
+ std::string msg;
// TransactionTooLargeException is a checked exception, only throw from certain methods.
// TODO(b/28321379): Transaction size is the most common cause for FAILED_TRANSACTION
// but it is not the only one. The Binder driver can return BR_FAILED_REPLY
@@ -890,7 +891,7 @@
if (canThrowRemoteException && parcelSize > 200*1024) {
// bona fide large payload
exceptionToThrow = "android/os/TransactionTooLargeException";
- snprintf(msg, sizeof(msg)-1, "data parcel size %d bytes", parcelSize);
+ msg = base::StringPrintf("data parcel size %d bytes", parcelSize);
} else {
// Heuristic: a payload smaller than this threshold "shouldn't" be too
// big, so it's probably some other, more subtle problem. In practice
@@ -899,11 +900,10 @@
exceptionToThrow = (canThrowRemoteException)
? "android/os/DeadObjectException"
: "java/lang/RuntimeException";
- snprintf(msg, sizeof(msg) - 1,
- "Transaction failed on small parcel; remote process probably died, but "
- "this could also be caused by running out of binder buffer space");
+ msg = "Transaction failed on small parcel; remote process probably died, but "
+ "this could also be caused by running out of binder buffer space";
}
- jniThrowException(env, exceptionToThrow, msg);
+ jniThrowException(env, exceptionToThrow, msg.c_str());
} break;
case FDS_NOT_ALLOWED:
jniThrowException(env, "java/lang/RuntimeException",
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cf10504..343bc1c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -342,22 +342,6 @@
<!-- Mask to use when checking skb mark defined in config_networkWakeupPacketMark above. -->
<integer name="config_networkWakeupPacketMask">0</integer>
- <!-- Whether the APF Filter in the device should filter out IEEE 802.3 Frames
- Those frames are identified by the field Eth-type having values
- less than 0x600 -->
- <bool translatable="false" name="config_apfDrop802_3Frames">true</bool>
-
- <!-- An array of Denylisted EtherType, packets with EtherTypes within this array
- will be dropped
- TODO: need to put proper values, these are for testing purposes only -->
- <integer-array translatable="false" name="config_apfEthTypeBlackList">
- <item>0x88A2</item>
- <item>0x88A4</item>
- <item>0x88B8</item>
- <item>0x88CD</item>
- <item>0x88E3</item>
- </integer-array>
-
<!-- Default value for ConnectivityManager.getMultipathPreference() on metered networks. Actual
device behaviour is controlled by Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE.
This is the default value of that setting. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1f71bf9..7736c1a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2016,8 +2016,6 @@
<java-symbol type="integer" name="config_networkAvoidBadWifi" />
<java-symbol type="integer" name="config_networkWakeupPacketMark" />
<java-symbol type="integer" name="config_networkWakeupPacketMask" />
- <java-symbol type="bool" name="config_apfDrop802_3Frames" />
- <java-symbol type="array" name="config_apfEthTypeBlackList" />
<java-symbol type="integer" name="config_networkDefaultDailyMultipathQuotaBytes" />
<java-symbol type="integer" name="config_networkMeteredMultipathPreference" />
<java-symbol type="array" name="config_networkSupportedKeepaliveCount" />
diff --git a/core/tests/GameManagerTests/OWNERS b/core/tests/GameManagerTests/OWNERS
new file mode 100644
index 0000000..0992440
--- /dev/null
+++ b/core/tests/GameManagerTests/OWNERS
@@ -0,0 +1 @@
+include /GAME_MANAGER_OWNERS
\ No newline at end of file
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index 04952bd..e2cdbf3 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -25,6 +25,11 @@
<option name="test-file-name" value="BinderDeathRecipientHelperApp2.apk" />
</target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <!-- TODO(b/254155965): Design a mechanism to finally remove this command. -->
+ <option name="run-command" value="settings put global device_config_sync_disabled 0" />
+ </target_preparer>
+
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceInteractionHelperInstaller" />
<option name="test-tag" value="FrameworksCoreTests" />
diff --git a/core/tests/coretests/src/android/app/AutomaticZenRuleTest.java b/core/tests/coretests/src/android/app/AutomaticZenRuleTest.java
new file mode 100644
index 0000000..282fdad
--- /dev/null
+++ b/core/tests/coretests/src/android/app/AutomaticZenRuleTest.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.fail;
+
+import android.content.ComponentName;
+import android.net.Uri;
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.base.Strings;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class AutomaticZenRuleTest {
+ private static final String CLASS = "android.app.AutomaticZenRule";
+
+ @Test
+ public void testLongFields_inConstructor() {
+ String longString = Strings.repeat("A", 65536);
+ Uri longUri = Uri.parse("uri://" + Strings.repeat("A", 65530));
+
+ // test both variants where there's an owner, and where there's a configuration activity
+ AutomaticZenRule rule1 = new AutomaticZenRule(
+ longString, // name
+ new ComponentName("pkg", longString), // owner
+ null, // configuration activity
+ longUri, // conditionId
+ null, // zen policy
+ 0, // interruption filter
+ true); // enabled
+
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH, rule1.getName().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ rule1.getConditionId().toString().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH, rule1.getOwner().getClassName().length());
+
+ AutomaticZenRule rule2 = new AutomaticZenRule(
+ longString, // name
+ null, // owner
+ new ComponentName(longString, "SomeClassName"), // configuration activity
+ longUri, // conditionId
+ null, // zen policy
+ 0, // interruption filter
+ false); // enabled
+
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH, rule2.getName().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ rule2.getConditionId().toString().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ rule2.getConfigurationActivity().getPackageName().length());
+ }
+
+ @Test
+ public void testLongFields_inSetters() {
+ String longString = Strings.repeat("A", 65536);
+ Uri longUri = Uri.parse("uri://" + Strings.repeat("A", 65530));
+
+ AutomaticZenRule rule = new AutomaticZenRule(
+ "sensible name",
+ new ComponentName("pkg", "ShortClass"),
+ null,
+ Uri.parse("uri://short"),
+ null, 0, true);
+
+ rule.setName(longString);
+ rule.setConditionId(longUri);
+ rule.setConfigurationActivity(new ComponentName(longString, longString));
+
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH, rule.getName().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ rule.getConditionId().toString().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ rule.getConfigurationActivity().getPackageName().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ rule.getConfigurationActivity().getClassName().length());
+ }
+
+ @Test
+ public void testLongInputsFromParcel() {
+ // Create a rule with long fields, set directly via reflection so that we can confirm that
+ // a rule with too-long fields that comes in via a parcel has its fields truncated directly.
+ AutomaticZenRule rule = new AutomaticZenRule(
+ "placeholder",
+ new ComponentName("place", "holder"),
+ null,
+ Uri.parse("uri://placeholder"),
+ null, 0, true);
+
+ try {
+ String longString = Strings.repeat("A", 65536);
+ Uri longUri = Uri.parse("uri://" + Strings.repeat("A", 65530));
+ Field name = Class.forName(CLASS).getDeclaredField("name");
+ name.setAccessible(true);
+ name.set(rule, longString);
+ Field conditionId = Class.forName(CLASS).getDeclaredField("conditionId");
+ conditionId.setAccessible(true);
+ conditionId.set(rule, longUri);
+ Field owner = Class.forName(CLASS).getDeclaredField("owner");
+ owner.setAccessible(true);
+ owner.set(rule, new ComponentName(longString, longString));
+ Field configActivity = Class.forName(CLASS).getDeclaredField("configurationActivity");
+ configActivity.setAccessible(true);
+ configActivity.set(rule, new ComponentName(longString, longString));
+ } catch (NoSuchFieldException e) {
+ fail(e.toString());
+ } catch (ClassNotFoundException e) {
+ fail(e.toString());
+ } catch (IllegalAccessException e) {
+ fail(e.toString());
+ }
+
+ Parcel parcel = Parcel.obtain();
+ rule.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ AutomaticZenRule fromParcel = new AutomaticZenRule(parcel);
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH, fromParcel.getName().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ fromParcel.getConditionId().toString().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ fromParcel.getConfigurationActivity().getPackageName().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ fromParcel.getConfigurationActivity().getClassName().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ fromParcel.getOwner().getPackageName().length());
+ assertEquals(AutomaticZenRule.MAX_STRING_LENGTH,
+ fromParcel.getOwner().getClassName().length());
+ }
+}
diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java
index a3bda8b..0fa5ec3 100644
--- a/core/tests/coretests/src/android/os/BundleTest.java
+++ b/core/tests/coretests/src/android/os/BundleTest.java
@@ -409,6 +409,69 @@
}
@Test
+ public void readFromParcel_withLazyValues_copiesUnderlyingParcel() {
+ Bundle bundle = new Bundle();
+ Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
+ bundle.putParcelable("key", parcelable);
+ bundle.putString("string", "value");
+ Parcel parcelledBundle = getParcelledBundle(bundle);
+
+ Bundle testBundle = new Bundle();
+ testBundle.setClassLoader(getClass().getClassLoader());
+ testBundle.readFromParcel(parcelledBundle);
+ // Recycle the parcel as it should have been copied
+ parcelledBundle.recycle();
+ assertThat(testBundle.getString("string")).isEqualTo("value");
+ assertThat(testBundle.<Parcelable>getParcelable("key")).isEqualTo(parcelable);
+ }
+
+ @Test
+ public void readFromParcelWithRwHelper_whenThrowingAndNotDefusing_throws() {
+ Bundle bundle = new Bundle();
+ Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
+ bundle.putParcelable("key", parcelable);
+ bundle.putString("string", "value");
+ Parcel parcelledBundle = getParcelledBundle(bundle);
+ parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
+
+ Bundle testBundle = new Bundle();
+ assertThrows(BadParcelableException.class,
+ () -> testBundle.readFromParcel(parcelledBundle));
+ }
+
+ @Test
+ public void readFromParcelWithRwHelper_whenThrowingAndDefusing_returnsNull() {
+ Bundle bundle = new Bundle();
+ Parcelable parcelable = new CustomParcelable(13, "Tiramisu");
+ bundle.putParcelable("key", parcelable);
+ bundle.putString("string", "value");
+ Parcel parcelledBundle = getParcelledBundle(bundle);
+ parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
+
+ Bundle.setShouldDefuse(true);
+ Bundle testBundle = new Bundle();
+ testBundle.readFromParcel(parcelledBundle);
+ // Recycle the parcel as it should not be referenced
+ parcelledBundle.recycle();
+ assertThat(testBundle.getString("string")).isNull();
+ assertThat(testBundle.<Parcelable>getParcelable("key")).isNull();
+ }
+
+ @Test
+ public void readFromParcelWithRwHelper_withoutLazyObject_returnsValue() {
+ Bundle bundle = new Bundle();
+ bundle.putString("string", "value");
+ Parcel parcelledBundle = getParcelledBundle(bundle);
+ parcelledBundle.setReadWriteHelper(new Parcel.ReadWriteHelper());
+
+ Bundle testBundle = new Bundle();
+ testBundle.readFromParcel(parcelledBundle);
+ // Recycle the parcel as it should not be referenced
+ parcelledBundle.recycle();
+ assertThat(testBundle.getString("string")).isEqualTo("value");
+ }
+
+ @Test
public void partialDeserialization_whenNotDefusing_throws() throws Exception {
Bundle.setShouldDefuse(false);
Bundle bundle = getMalformedBundle();
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index dbd918e..6245598 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -30,6 +30,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import java.util.Collection;
import java.util.Locale;
@@ -914,6 +915,51 @@
}
/**
+ * @hide
+ */
+ public abstract static class EcCurve {
+ private EcCurve() {}
+
+ /**
+ * @hide
+ */
+ public static int toKeymasterCurve(ECParameterSpec spec) {
+ int keySize = spec.getCurve().getField().getFieldSize();
+ switch (keySize) {
+ case 224:
+ return android.hardware.security.keymint.EcCurve.P_224;
+ case 256:
+ return android.hardware.security.keymint.EcCurve.P_256;
+ case 384:
+ return android.hardware.security.keymint.EcCurve.P_384;
+ case 521:
+ return android.hardware.security.keymint.EcCurve.P_521;
+ default:
+ return -1;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static int fromKeymasterCurve(int ecCurve) {
+ switch (ecCurve) {
+ case android.hardware.security.keymint.EcCurve.P_224:
+ return 224;
+ case android.hardware.security.keymint.EcCurve.P_256:
+ case android.hardware.security.keymint.EcCurve.CURVE_25519:
+ return 256;
+ case android.hardware.security.keymint.EcCurve.P_384:
+ return 384;
+ case android.hardware.security.keymint.EcCurve.P_521:
+ return 521;
+ default:
+ return -1;
+ }
+ }
+ }
+
+ /**
* Namespaces provide system developers and vendors with a way to use keystore without
* requiring an applications uid. Namespaces can be configured using SEPolicy.
* See <a href="https://source.android.com/security/keystore#access-control">
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
index 5216a90..ace2053 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java
@@ -203,6 +203,11 @@
for (Authorization a : key.getAuthorizations()) {
if (a.keyParameter.tag == KeymasterDefs.KM_TAG_KEY_SIZE) {
keySizeBits = KeyStore2ParameterUtils.getUnsignedInt(a);
+ break;
+ } else if (a.keyParameter.tag == KeymasterDefs.KM_TAG_EC_CURVE) {
+ keySizeBits = KeyProperties.EcCurve.fromKeymasterCurve(
+ a.keyParameter.value.getEcCurve());
+ break;
}
}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index 9d424e9..f05cdc5 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -66,6 +66,7 @@
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.interfaces.ECKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -566,6 +567,22 @@
spec.getMaxUsageCount()
));
}
+ if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(key.getAlgorithm())) {
+ if (key instanceof ECKey) {
+ ECKey ecKey = (ECKey) key;
+ importArgs.add(KeyStore2ParameterUtils.makeEnum(
+ KeymasterDefs.KM_TAG_EC_CURVE,
+ KeyProperties.EcCurve.toKeymasterCurve(ecKey.getParams())
+ ));
+ }
+ }
+ /* TODO: check for Ed25519(EdDSA) or X25519(XDH) key algorithm and
+ * add import args for KM_TAG_EC_CURVE as EcCurve.CURVE_25519.
+ * Currently conscrypt does not support EdDSA key import and XDH keys are not an
+ * instance of XECKey, hence these conditions are not added, once it is fully
+ * implemented by conscrypt, we can add CURVE_25519 argument for EdDSA and XDH
+ * algorithms.
+ */
} catch (IllegalArgumentException | IllegalStateException e) {
throw new KeyStoreException(e);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 54d62ed..978ad8a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -429,7 +429,8 @@
}
@Override
- public @Nullable SplashScreenView get() {
+ @Nullable
+ public SplashScreenView get() {
synchronized (this) {
while (!mIsViewSet) {
try {
@@ -690,7 +691,7 @@
private final TaskSnapshotWindow mTaskSnapshotWindow;
private SplashScreenView mContentView;
private boolean mSetSplashScreen;
- private @StartingWindowType int mSuggestType;
+ @StartingWindowType private int mSuggestType;
private int mBGColor;
private final long mCreateTime;
private int mSystemBarAppearance;
@@ -731,7 +732,7 @@
// Reset the system bar color which set by splash screen, make it align to the app.
private void clearSystemBarColor() {
- if (mDecorView == null) {
+ if (mDecorView == null || !mDecorView.isAttachedToWindow()) {
return;
}
if (mDecorView.getLayoutParams() instanceof WindowManager.LayoutParams) {
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 18135f2..b7282218 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -431,6 +431,18 @@
return "AUDIO_FORMAT_APTX_TWSP";
case /* AUDIO_FORMAT_LC3 */ 0x2B000000:
return "AUDIO_FORMAT_LC3";
+ case /* AUDIO_FORMAT_MPEGH */ 0x2C000000:
+ return "AUDIO_FORMAT_MPEGH";
+ case /* AUDIO_FORMAT_IEC60958 */ 0x2D000000:
+ return "AUDIO_FORMAT_IEC60958";
+ case /* AUDIO_FORMAT_DTS_UHD */ 0x2E000000:
+ return "AUDIO_FORMAT_DTS_UHD";
+ case /* AUDIO_FORMAT_DRA */ 0x2F000000:
+ return "AUDIO_FORMAT_DRA";
+ case /* AUDIO_FORMAT_APTX_ADAPTIVE_QLEA */ 0x30000000:
+ return "AUDIO_FORMAT_APTX_ADAPTIVE_QLEA";
+ case /* AUDIO_FORMAT_APTX_ADAPTIVE_R4 */ 0x31000000:
+ return "AUDIO_FORMAT_APTX_ADAPTIVE_R4";
/* Aliases */
case /* AUDIO_FORMAT_PCM_16_BIT */ 0x1:
@@ -503,10 +515,14 @@
return "AUDIO_FORMAT_MAT_2_0"; // (MAT | MAT_SUB_2_0)
case /* AUDIO_FORMAT_MAT_2_1 */ 0x24000003:
return "AUDIO_FORMAT_MAT_2_1"; // (MAT | MAT_SUB_2_1)
- case /* AUDIO_FORMAT_DTS_UHD */ 0x2E000000:
- return "AUDIO_FORMAT_DTS_UHD";
- case /* AUDIO_FORMAT_DRA */ 0x2F000000:
- return "AUDIO_FORMAT_DRA";
+ case /* AUDIO_FORMAT_MPEGH_SUB_BL_L3 */ 0x2C000013:
+ return "AUDIO_FORMAT_MPEGH_SUB_BL_L3";
+ case /* AUDIO_FORMAT_MPEGH_SUB_BL_L4 */ 0x2C000014:
+ return "AUDIO_FORMAT_MPEGH_SUB_BL_L4";
+ case /* AUDIO_FORMAT_MPEGH_SUB_LC_L3 */ 0x2C000023:
+ return "AUDIO_FORMAT_MPEGH_SUB_LC_L3";
+ case /* AUDIO_FORMAT_MPEGH_SUB_LC_L4 */ 0x2C000024:
+ return "AUDIO_FORMAT_MPEGH_SUB_LC_L4";
default:
return "AUDIO_FORMAT_(" + audioFormat + ")";
}
@@ -2400,4 +2416,3 @@
*/
final static int NATIVE_EVENT_ROUTING_CHANGE = 1000;
}
-
diff --git a/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java b/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
index 23195af..00f1c01 100644
--- a/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
+++ b/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java
@@ -33,6 +33,7 @@
import android.view.ViewGroup;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.keyguard.dagger.KeyguardBouncerScope;
import com.android.systemui.dagger.qualifiers.Main;
@@ -208,7 +209,7 @@
hide();
if (mKeyguardCallback != null) {
mKeyguardCallback.dismiss(/* securityVerified= */ true, userId,
- /* bypassSecondaryLockScreen= */true);
+ /* bypassSecondaryLockScreen= */true, SecurityMode.Invalid);
}
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
index eb418ff..b8fcb10 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java
@@ -179,7 +179,7 @@
if (dismissKeyguard) {
mDismissing = true;
mLatencyTracker.onActionStart(LatencyTracker.ACTION_LOCKSCREEN_UNLOCK);
- getKeyguardSecurityCallback().dismiss(true, userId);
+ getKeyguardSecurityCallback().dismiss(true, userId, getSecurityMode());
}
} else {
if (isValidPassword) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
index 12fa401..befd59b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostViewController.java
@@ -90,7 +90,7 @@
Log.i(TAG, "TrustAgent dismissed Keyguard.");
}
mSecurityCallback.dismiss(false /* authenticated */, userId,
- /* bypassSecondaryLockScreen */ false);
+ /* bypassSecondaryLockScreen */ false, SecurityMode.Invalid);
} else {
mViewMediatorCallback.playTrustedSound();
}
@@ -102,9 +102,9 @@
@Override
public boolean dismiss(boolean authenticated, int targetUserId,
- boolean bypassSecondaryLockScreen) {
+ boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) {
return mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
- authenticated, targetUserId, bypassSecondaryLockScreen);
+ authenticated, targetUserId, bypassSecondaryLockScreen, expectedSecurityMode);
}
@Override
@@ -212,7 +212,8 @@
* @return True if the keyguard is done.
*/
public boolean dismiss(int targetUserId) {
- return mSecurityCallback.dismiss(false, targetUserId, false);
+ return mSecurityCallback.dismiss(false, targetUserId, false,
+ getCurrentSecurityMode());
}
/**
@@ -355,10 +356,10 @@
}
public boolean handleBackKey() {
- if (mKeyguardSecurityContainerController.getCurrentSecurityMode()
- != SecurityMode.None) {
+ SecurityMode securityMode = mKeyguardSecurityContainerController.getCurrentSecurityMode();
+ if (securityMode != SecurityMode.None) {
mKeyguardSecurityContainerController.dismiss(
- false, KeyguardUpdateMonitor.getCurrentUser());
+ false, KeyguardUpdateMonitor.getCurrentUser(), securityMode);
return true;
}
return false;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
index 98ac640..87300c3 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardInputViewController.java
@@ -59,10 +59,11 @@
return false;
}
@Override
- public void dismiss(boolean securityVerified, int targetUserId) { }
+ public void dismiss(boolean securityVerified, int targetUserId,
+ SecurityMode expectedSecurityMode) { }
@Override
public void dismiss(boolean authenticated, int targetId,
- boolean bypassSecondaryLockScreen) { }
+ boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) { }
@Override
public void onUserInput() { }
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 39c3949..1a59b82 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -171,7 +171,7 @@
if (dismissKeyguard) {
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
mLatencyTracker.onActionStart(LatencyTracker.ACTION_LOCKSCREEN_UNLOCK);
- getKeyguardSecurityCallback().dismiss(true, userId);
+ getKeyguardSecurityCallback().dismiss(true, userId, SecurityMode.Pattern);
}
} else {
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
index e384727..bc72f79 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -15,14 +15,17 @@
*/
package com.android.keyguard;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+
public interface KeyguardSecurityCallback {
/**
* Dismiss the given security screen.
* @param securityVerified true if the user correctly entered credentials for the given screen.
* @param targetUserId a user that needs to be the foreground user at the dismissal completion.
+ * @param expectedSecurityMode The security mode that is invoking this dismiss.
*/
- void dismiss(boolean securityVerified, int targetUserId);
+ void dismiss(boolean securityVerified, int targetUserId, SecurityMode expectedSecurityMode);
/**
* Dismiss the given security screen.
@@ -30,8 +33,10 @@
* @param targetUserId a user that needs to be the foreground user at the dismissal completion.
* @param bypassSecondaryLockScreen true if the user can bypass the secondary lock screen,
* if any, during this dismissal.
+ * @param expectedSecurityMode The security mode that is invoking this dismiss.
*/
- void dismiss(boolean securityVerified, int targetUserId, boolean bypassSecondaryLockScreen);
+ void dismiss(boolean securityVerified, int targetUserId, boolean bypassSecondaryLockScreen,
+ SecurityMode expectedSecurityMode);
/**
* Manually report user activity to keep the device awake.
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index cce516d..12bb47b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -233,7 +233,12 @@
// Used to notify the container when something interesting happens.
public interface SecurityCallback {
- boolean dismiss(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen);
+ /**
+ * Potentially dismiss the current security screen, after validating that all device
+ * security has been unlocked. Otherwise show the next screen.
+ */
+ boolean dismiss(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen,
+ SecurityMode expectedSecurityMode);
void userActivity();
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 19a2d9e..2b9553d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -153,14 +153,17 @@
}
@Override
- public void dismiss(boolean authenticated, int targetId) {
- dismiss(authenticated, targetId, /* bypassSecondaryLockScreen */ false);
+ public void dismiss(boolean authenticated, int targetId,
+ SecurityMode expectedSecurityMode) {
+ dismiss(authenticated, targetId, /* bypassSecondaryLockScreen */ false,
+ expectedSecurityMode);
}
@Override
public void dismiss(boolean authenticated, int targetId,
- boolean bypassSecondaryLockScreen) {
- mSecurityCallback.dismiss(authenticated, targetId, bypassSecondaryLockScreen);
+ boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) {
+ mSecurityCallback.dismiss(authenticated, targetId, bypassSecondaryLockScreen,
+ expectedSecurityMode);
}
public boolean isVerifyUnlockOnly() {
@@ -350,8 +353,13 @@
return mCurrentSecurityMode;
}
- public void dismiss(boolean authenticated, int targetUserId) {
- mKeyguardSecurityCallback.dismiss(authenticated, targetUserId);
+ /**
+ * Potentially dismiss the current security screen, after validating that all device
+ * security has been unlocked. Otherwise show the next screen.
+ */
+ public void dismiss(boolean authenticated, int targetUserId,
+ SecurityMode expectedSecurityMode) {
+ mKeyguardSecurityCallback.dismiss(authenticated, targetUserId, expectedSecurityMode);
}
public void reset() {
@@ -410,12 +418,21 @@
* completion.
* @param bypassSecondaryLockScreen true if the user is allowed to bypass the secondary
* secondary lock screen requirement, if any.
+ * @param expectedSecurityMode SecurityMode that is invoking this request. SecurityMode.Invalid
+ * indicates that no check should be done
* @return true if keyguard is done
*/
public boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId,
- boolean bypassSecondaryLockScreen) {
+ boolean bypassSecondaryLockScreen, SecurityMode expectedSecurityMode) {
if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
+ if (expectedSecurityMode != SecurityMode.Invalid
+ && expectedSecurityMode != getCurrentSecurityMode()) {
+ Log.w(TAG, "Attempted to invoke showNextSecurityScreenOrFinish with securityMode "
+ + expectedSecurityMode + ", but current mode is " + getCurrentSecurityMode());
+ return false;
+ }
+
boolean finish = false;
boolean strongAuth = false;
int eventSubtype = -1;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index e337123..821b2e1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -170,7 +170,8 @@
mRemainingAttempts = -1;
mShowDefaultMessage = true;
getKeyguardSecurityCallback().dismiss(
- true, KeyguardUpdateMonitor.getCurrentUser());
+ true, KeyguardUpdateMonitor.getCurrentUser(),
+ SecurityMode.SimPin);
} else {
mShowDefaultMessage = false;
if (result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
index 47aa43b..203f9b6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java
@@ -69,7 +69,8 @@
if (simState == TelephonyManager.SIM_STATE_READY) {
mRemainingAttempts = -1;
mShowDefaultMessage = true;
- getKeyguardSecurityCallback().dismiss(true, KeyguardUpdateMonitor.getCurrentUser());
+ getKeyguardSecurityCallback().dismiss(true, KeyguardUpdateMonitor.getCurrentUser(),
+ SecurityMode.SimPuk);
} else {
resetState();
}
@@ -278,7 +279,8 @@
mShowDefaultMessage = true;
getKeyguardSecurityCallback().dismiss(
- true, KeyguardUpdateMonitor.getCurrentUser());
+ true, KeyguardUpdateMonitor.getCurrentUser(),
+ SecurityMode.SimPuk);
} else {
mShowDefaultMessage = false;
if (result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 0783eeec..90bcb0fe 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1641,7 +1641,7 @@
try {
callback.onKeyguardExitResult(true);
} catch (RemoteException e) {
- Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
+ Slog.w(TAG, "Failed to call onKeyguardExitResult(true)", e);
}
} else {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
index dffad6c..80385e6 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/AdminSecondaryLockScreenControllerTest.java
@@ -44,6 +44,7 @@
import androidx.test.filters.SmallTest;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.systemui.SysuiTestCase;
import org.junit.After;
@@ -190,7 +191,7 @@
private void verifyViewDismissed(SurfaceView v) throws Exception {
verify(mKeyguardSecurityContainer).removeView(v);
- verify(mKeyguardCallback).dismiss(true, TARGET_USER_ID, true);
+ verify(mKeyguardCallback).dismiss(true, TARGET_USER_ID, true, SecurityMode.Invalid);
assertThat(mContext.isBound(mComponentName)).isFalse();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index 4d33430..efc9921 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -21,7 +21,10 @@
import static com.android.keyguard.KeyguardSecurityContainer.MODE_DEFAULT;
import static com.android.keyguard.KeyguardSecurityContainer.MODE_ONE_HANDED;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
@@ -69,6 +72,7 @@
@TestableLooper.RunWithLooper()
public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
private static final int VIEW_WIDTH = 1600;
+ private static final int TARGET_USER_ID = 100;
@Rule
public MockitoRule mRule = MockitoJUnit.rule();
@@ -299,4 +303,42 @@
verify(mUserSwitcherController)
.removeUserSwitchCallback(any(UserSwitcherController.UserSwitchCallback.class));
}
+
+ @Test
+ public void showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() {
+ // GIVEN the current security method is SimPin
+ when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
+ when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(TARGET_USER_ID)).thenReturn(false);
+ mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.SimPin);
+
+ // WHEN a request is made from the SimPin screens to show the next security method
+ when(mKeyguardSecurityModel.getSecurityMode(TARGET_USER_ID)).thenReturn(SecurityMode.PIN);
+ mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
+ /* authenticated= */true,
+ TARGET_USER_ID,
+ /* bypassSecondaryLockScreen= */true,
+ SecurityMode.SimPin);
+
+ // THEN the next security method of PIN is set, and the keyguard is not marked as done
+ verify(mSecurityCallback, never()).finish(anyBoolean(), anyInt());
+ assertThat(mKeyguardSecurityContainerController.getCurrentSecurityMode())
+ .isEqualTo(SecurityMode.PIN);
+ }
+
+ @Test
+ public void showNextSecurityScreenOrFinish_ignoresCallWhenSecurityMethodHasChanged() {
+ //GIVEN current security mode has been set to PIN
+ mKeyguardSecurityContainerController.showSecurityScreen(SecurityMode.PIN);
+
+ //WHEN a request comes from SimPin to dismiss the security screens
+ boolean keyguardDone = mKeyguardSecurityContainerController.showNextSecurityScreenOrFinish(
+ /* authenticated= */true,
+ TARGET_USER_ID,
+ /* bypassSecondaryLockScreen= */true,
+ SecurityMode.SimPin);
+
+ //THEN no action has happened, which will not dismiss the security screens
+ assertThat(keyguardDone).isEqualTo(false);
+ verify(mKeyguardUpdateMonitor, never()).getUserHasTrust(anyInt());
+ }
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index f7b05f2..ec8745a 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -19,12 +19,10 @@
import static android.Manifest.permission.ACCESS_MTP;
import static android.Manifest.permission.INSTALL_PACKAGES;
import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
-import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
import static android.app.AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES;
-import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_ONE_SHOT;
@@ -4461,11 +4459,7 @@
}
}
- // Determine if caller is holding runtime permission
- final boolean hasWrite = StorageManager.checkPermissionAndCheckOp(mContext, false, 0,
- uid, packageName, WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE);
-
- // We're only willing to give out installer access if they also hold
+ // We're only willing to give out installer access if they hold
// runtime permission; this is a firm CDD requirement
final boolean hasInstall = mIPackageManager.checkUidPermission(INSTALL_PACKAGES,
uid) == PERMISSION_GRANTED;
@@ -4481,7 +4475,7 @@
break;
}
}
- if ((hasInstall || hasInstallOp) && hasWrite) {
+ if (hasInstall || hasInstallOp) {
return StorageManager.MOUNT_MODE_EXTERNAL_INSTALLER;
}
return StorageManager.MOUNT_MODE_EXTERNAL_DEFAULT;
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index 3f1d1fe..ae50b23 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -186,6 +186,10 @@
synchronized (mVpns) {
for (int i = 0; i < mVpns.size(); i++) {
pw.println(mVpns.keyAt(i) + ": " + mVpns.valueAt(i).getPackage());
+ pw.increaseIndent();
+ mVpns.valueAt(i).dump(pw);
+ pw.decreaseIndent();
+ pw.println();
}
pw.decreaseIndent();
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 6b731c3..8dc02c1 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -4794,6 +4794,7 @@
private abstract class Session extends IAccountAuthenticatorResponse.Stub
implements IBinder.DeathRecipient, ServiceConnection {
+ private final Object mSessionLock = new Object();
IAccountManagerResponse mResponse;
final String mAccountType;
final boolean mExpectActivityLaunch;
@@ -4959,9 +4960,11 @@
}
private void unbind() {
- if (mAuthenticator != null) {
- mAuthenticator = null;
- mContext.unbindService(this);
+ synchronized (mSessionLock) {
+ if (mAuthenticator != null) {
+ mAuthenticator = null;
+ mContext.unbindService(this);
+ }
}
}
@@ -4971,12 +4974,14 @@
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
- mAuthenticator = IAccountAuthenticator.Stub.asInterface(service);
- try {
- run();
- } catch (RemoteException e) {
- onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION,
- "remote exception");
+ synchronized (mSessionLock) {
+ mAuthenticator = IAccountAuthenticator.Stub.asInterface(service);
+ try {
+ run();
+ } catch (RemoteException e) {
+ onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION,
+ "remote exception");
+ }
}
}
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 6a000d9..0741d46 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -127,6 +127,8 @@
import android.system.keystore2.KeyPermission;
import android.text.TextUtils;
import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
+import android.util.LocalLog;
import android.util.Log;
import android.util.Range;
@@ -296,6 +298,10 @@
return mVpnProfileStore;
}
+ private static final int MAX_EVENTS_LOGS = 20;
+ private final LocalLog mUnderlyNetworkChanges = new LocalLog(MAX_EVENTS_LOGS);
+ private final LocalLog mVpnManagerEvents = new LocalLog(MAX_EVENTS_LOGS);
+
/**
* Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
* only applies to {@link VpnService} connections.
@@ -841,6 +847,9 @@
int errorCode, @NonNull final String packageName, @Nullable final String sessionKey,
@NonNull final VpnProfileState profileState, @Nullable final Network underlyingNetwork,
@Nullable final NetworkCapabilities nc, @Nullable final LinkProperties lp) {
+ mVpnManagerEvents.log("Event class=" + getVpnManagerEventClassName(errorClass)
+ + ", err=" + getVpnManagerEventErrorName(errorCode) + " for " + packageName
+ + " on session " + sessionKey);
final Intent intent = buildVpnManagerEventIntent(category, errorClass, errorCode,
packageName, sessionKey, profileState, underlyingNetwork, nc, lp);
return sendEventToVpnManagerApp(intent, packageName);
@@ -1572,6 +1581,7 @@
? Arrays.asList(mConfig.underlyingNetworks) : null);
mNetworkCapabilities = capsBuilder.build();
+ logUnderlyNetworkChanges(mNetworkCapabilities.getUnderlyingNetworks());
mNetworkAgent = mDeps.newNetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
mNetworkCapabilities, lp,
new NetworkScore.Builder().setLegacyInt(VPN_DEFAULT_SCORE).build(),
@@ -1599,6 +1609,11 @@
}
}
+ private void logUnderlyNetworkChanges(List<Network> networks) {
+ mUnderlyNetworkChanges.log("Switch to "
+ + ((networks != null) ? TextUtils.join(", ", networks) : "null"));
+ }
+
private void agentDisconnect(NetworkAgent networkAgent) {
if (networkAgent != null) {
networkAgent.unregister();
@@ -4372,6 +4387,7 @@
// TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from
// ConnectivityServiceTest.
if (SdkLevel.isAtLeastT()) {
+ mVpnManagerEvents.log(packageName + " stopped");
sendEventToVpnManagerApp(intent, packageName);
}
}
@@ -4539,8 +4555,10 @@
/** Proxy to allow different testing setups */
// TODO: b/240492694 Remove VpnNetworkAgentWrapper and this method when
// NetworkAgent#setUnderlyingNetworks can be un-finalized.
- private static void doSetUnderlyingNetworks(
+ private void doSetUnderlyingNetworks(
@NonNull NetworkAgent agent, @NonNull List<Network> networks) {
+ logUnderlyNetworkChanges(networks);
+
if (agent instanceof VpnNetworkAgentWrapper) {
((VpnNetworkAgentWrapper) agent).doSetUnderlyingNetworks(networks);
} else {
@@ -4659,4 +4677,57 @@
static Range<Integer> createUidRangeForUser(int userId) {
return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1);
}
+
+ private String getVpnManagerEventClassName(int code) {
+ switch (code) {
+ case VpnManager.ERROR_CLASS_NOT_RECOVERABLE:
+ return "ERROR_CLASS_NOT_RECOVERABLE";
+ case VpnManager.ERROR_CLASS_RECOVERABLE:
+ return "ERROR_CLASS_RECOVERABLE";
+ default:
+ return "UNKNOWN_CLASS";
+ }
+ }
+
+ private String getVpnManagerEventErrorName(int code) {
+ switch (code) {
+ case VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST:
+ return "ERROR_CODE_NETWORK_UNKNOWN_HOST";
+ case VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT:
+ return "ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT";
+ case VpnManager.ERROR_CODE_NETWORK_IO:
+ return "ERROR_CODE_NETWORK_IO";
+ case VpnManager.ERROR_CODE_NETWORK_LOST:
+ return "ERROR_CODE_NETWORK_LOST";
+ default:
+ return "UNKNOWN_ERROR";
+ }
+ }
+
+ /** Dumps VPN state. */
+ public void dump(IndentingPrintWriter pw) {
+ synchronized (Vpn.this) {
+ pw.println("Active package name: " + mPackage);
+ pw.println("Active vpn type: " + getActiveVpnType());
+ pw.println("NetworkCapabilities: " + mNetworkCapabilities);
+ if (isIkev2VpnRunner()) {
+ final IkeV2VpnRunner runner = ((IkeV2VpnRunner) mVpnRunner);
+ pw.println("Token: " + runner.mSessionKey);
+ pw.println("MOBIKE " + (runner.mMobikeEnabled ? "enabled" : "disabled"));
+ if (mDataStallSuspected) pw.println("Data stall suspected");
+ if (runner.mScheduledHandleDataStallFuture != null) {
+ pw.println("Reset session scheduled");
+ }
+ }
+ pw.println("mUnderlyNetworkChanges (most recent first):");
+ pw.increaseIndent();
+ mUnderlyNetworkChanges.reverseDump(pw);
+ pw.decreaseIndent();
+
+ pw.println("mVpnManagerEvent (most recent first):");
+ pw.increaseIndent();
+ mVpnManagerEvents.reverseDump(pw);
+ pw.decreaseIndent();
+ }
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 018a2fc..2cc0073 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4927,7 +4927,16 @@
}
enforcePolicyAccess(Binder.getCallingUid(), "addAutomaticZenRule");
- return mZenModeHelper.addAutomaticZenRule(pkg, automaticZenRule,
+ // If the caller is system, take the package name from the rule's owner rather than
+ // from the caller's package.
+ String rulePkg = pkg;
+ if (isCallingUidSystem()) {
+ if (automaticZenRule.getOwner() != null) {
+ rulePkg = automaticZenRule.getOwner().getPackageName();
+ }
+ }
+
+ return mZenModeHelper.addAutomaticZenRule(rulePkg, automaticZenRule,
"addAutomaticZenRule");
}
@@ -7850,7 +7859,8 @@
&& (record.getSuppressedVisualEffects() & SUPPRESSED_EFFECT_STATUS_BAR) != 0;
if (!record.isUpdate
&& record.getImportance() > IMPORTANCE_MIN
- && !suppressedByDnd) {
+ && !suppressedByDnd
+ && isNotificationForCurrentUser(record)) {
sendAccessibilityEvent(record);
sentAccessibilityEvent = true;
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 2b00ad7..85c47a0 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -314,7 +314,7 @@
public String addAutomaticZenRule(String pkg, AutomaticZenRule automaticZenRule,
String reason) {
- if (!isSystemRule(automaticZenRule)) {
+ if (!ZenModeConfig.SYSTEM_AUTHORITY.equals(pkg)) {
PackageItemInfo component = getServiceInfo(automaticZenRule.getOwner());
if (component == null) {
component = getActivityInfo(automaticZenRule.getConfigurationActivity());
@@ -570,11 +570,6 @@
}
}
- private boolean isSystemRule(AutomaticZenRule rule) {
- return rule.getOwner() != null
- && ZenModeConfig.SYSTEM_AUTHORITY.equals(rule.getOwner().getPackageName());
- }
-
private ServiceInfo getServiceInfo(ComponentName owner) {
Intent queryIntent = new Intent();
queryIntent.setComponent(owner);
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 5a01ccb..e411880 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -149,8 +149,6 @@
@GuardedBy("mLock") @Status private int mLastExecutionStatus = STATUS_OK;
- @GuardedBy("mLock") private long mLastExecutionStartTimeMs;
- @GuardedBy("mLock") private long mLastExecutionDurationIncludingSleepMs;
@GuardedBy("mLock") private long mLastExecutionStartUptimeMs;
@GuardedBy("mLock") private long mLastExecutionDurationMs;
@@ -229,10 +227,6 @@
writer.println(mFinishedPostBootUpdate);
writer.print("mLastExecutionStatus:");
writer.println(mLastExecutionStatus);
- writer.print("mLastExecutionStartTimeMs:");
- writer.println(mLastExecutionStartTimeMs);
- writer.print("mLastExecutionDurationIncludingSleepMs:");
- writer.println(mLastExecutionDurationIncludingSleepMs);
writer.print("mLastExecutionStartUptimeMs:");
writer.println(mLastExecutionStartUptimeMs);
writer.print("mLastExecutionDurationMs:");
@@ -539,8 +533,6 @@
private boolean runIdleOptimization(
PackageManagerService pm, List<String> pkgs, boolean isPostBootUpdate) {
synchronized (mLock) {
- mLastExecutionStartTimeMs = SystemClock.elapsedRealtime();
- mLastExecutionDurationIncludingSleepMs = -1;
mLastExecutionStartUptimeMs = SystemClock.uptimeMillis();
mLastExecutionDurationMs = -1;
}
@@ -549,8 +541,6 @@
logStatus(status);
synchronized (mLock) {
mLastExecutionStatus = status;
- mLastExecutionDurationIncludingSleepMs =
- SystemClock.elapsedRealtime() - mLastExecutionStartTimeMs;
mLastExecutionDurationMs = SystemClock.uptimeMillis() - mLastExecutionStartUptimeMs;
}
@@ -954,10 +944,9 @@
synchronized (mLock) {
status = mLastExecutionStatus;
durationMs = mLastExecutionDurationMs;
- durationIncludingSleepMs = mLastExecutionDurationIncludingSleepMs;
}
- mStatsLogger.write(status, params.getStopReason(), durationMs, durationIncludingSleepMs);
+ mStatsLogger.write(status, params.getStopReason(), durationMs);
}
/** Injector pattern for testing purpose */
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 46691a6..1e64701 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3630,7 +3630,7 @@
fd = ParcelFileDescriptor.dup(getInFileDescriptor());
}
if (sizeBytes <= 0) {
- getErrPrintWriter().println("Error: must specify a APK size");
+ getErrPrintWriter().println("Error: must specify an APK size");
return 1;
}
diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
index 905bcf9..1407530 100644
--- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
+++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java
@@ -320,12 +320,15 @@
public static class BackgroundDexoptJobStatsLogger {
/** Writes background dexopt job stats to statsd. */
public void write(@BackgroundDexOptService.Status int status,
- @JobParameters.StopReason int cancellationReason, long durationMs,
- long durationIncludingSleepMs) {
- ArtStatsLog.write(ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED,
+ @JobParameters.StopReason int cancellationReason,
+ long durationMs) {
+ ArtStatsLog.write(
+ ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED,
STATUS_MAP.getOrDefault(status,
ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__STATUS__STATUS_UNKNOWN),
- cancellationReason, durationMs, durationIncludingSleepMs);
+ cancellationReason,
+ durationMs,
+ 0); // deprecated, used to be durationIncludingSleepMs
}
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index d34682d..1e13333 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -2664,7 +2664,6 @@
final Permission bp = mRegistry.getPermission(permName);
final boolean appSupportsRuntimePermissions =
pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
- String legacyActivityRecognitionPermission = null;
if (DEBUG_INSTALL && bp != null) {
Log.i(TAG, "Package " + friendlyName
@@ -2688,47 +2687,12 @@
// Cache newImplicitPermissions before modifing permissionsState as for the
// shared uids the original and new state are the same object
if (!origState.hasPermissionState(permName)
- && (pkg.getImplicitPermissions().contains(permName)
- || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
- if (pkg.getImplicitPermissions().contains(permName)) {
+ && (pkg.getImplicitPermissions().contains(permName))) {
// If permName is an implicit permission, try to auto-grant
newImplicitPermissions.add(permName);
-
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, permName + " is newly added for " + friendlyName);
}
- } else {
- // Special case for Activity Recognition permission. Even if AR
- // permission is not an implicit permission we want to add it to the
- // list (try to auto-grant it) if the app was installed on a device
- // before AR permission was split, regardless of if the app now requests
- // the new AR permission or has updated its target SDK and AR is no
- // longer implicit to it. This is a compatibility workaround for apps
- // when AR permission was split in Q.
- // TODO(zhanghai): This calls into SystemConfig, which generally
- // shouldn't cause deadlock, but maybe we should keep a cache of the
- // split permission list and just eliminate the possibility.
- final List<PermissionManager.SplitPermissionInfo> permissionList =
- getSplitPermissionInfos();
- int numSplitPerms = permissionList.size();
- for (int splitPermNum = 0; splitPermNum < numSplitPerms;
- splitPermNum++) {
- PermissionManager.SplitPermissionInfo sp = permissionList.get(
- splitPermNum);
- String splitPermName = sp.getSplitPermission();
- if (sp.getNewPermissions().contains(permName)
- && origState.isPermissionGranted(splitPermName)) {
- legacyActivityRecognitionPermission = splitPermName;
- newImplicitPermissions.add(permName);
-
- if (DEBUG_PERMISSIONS) {
- Slog.i(TAG, permName + " is newly added for "
- + friendlyName);
- }
- break;
- }
- }
- }
}
// TODO(b/140256621): The package instant app method has been removed
@@ -2862,8 +2826,7 @@
// Hard restricted permissions cannot be held.
} else if (!permissionPolicyInitialized
|| (!hardRestricted || restrictionExempt)) {
- if ((origPermState != null && origPermState.isGranted())
- || legacyActivityRecognitionPermission != null) {
+ if ((origPermState != null && origPermState.isGranted())) {
if (!uidState.grantPermission(bp)) {
wasChanged = true;
}
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index 1ec191e..e14bbbd 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -20,16 +20,15 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import android.app.ActivityManager.RunningTaskInfo;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArraySet;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledLambda;
-import java.util.Comparator;
-import java.util.Iterator;
+import java.util.ArrayList;
import java.util.List;
-import java.util.TreeSet;
/**
* Class for resolving the set of running tasks in the system.
@@ -41,15 +40,13 @@
static final int FLAG_CROSS_USERS = 1 << 2;
static final int FLAG_KEEP_INTENT_EXTRA = 1 << 3;
- // Comparator to sort by last active time (descending)
- private static final Comparator<Task> LAST_ACTIVE_TIME_COMPARATOR =
- (o1, o2) -> {
- return o1.lastActiveTime == o2.lastActiveTime
- ? Integer.signum(o2.mTaskId - o1.mTaskId) :
- Long.signum(o2.lastActiveTime - o1.lastActiveTime);
- };
-
- private final TreeSet<Task> mTmpSortedSet = new TreeSet<>(LAST_ACTIVE_TIME_COMPARATOR);
+ // Tasks are sorted in order {focusedVisibleTasks, visibleTasks, invisibleTasks}.
+ private final ArrayList<Task> mTmpSortedTasks = new ArrayList<>();
+ // mTmpVisibleTasks, mTmpInvisibleTasks and mTmpFocusedTasks are sorted from top
+ // to bottom.
+ private final ArrayList<Task> mTmpVisibleTasks = new ArrayList<>();
+ private final ArrayList<Task> mTmpInvisibleTasks = new ArrayList<>();
+ private final ArrayList<Task> mTmpFocusedTasks = new ArrayList<>();
private int mCallingUid;
private int mUserId;
@@ -67,8 +64,6 @@
return;
}
- // Gather all of the tasks across all of the tasks, and add them to the sorted set
- mTmpSortedSet.clear();
mCallingUid = callingUid;
mUserId = UserHandle.getUserId(callingUid);
mCrossUser = (flags & FLAG_CROSS_USERS) == FLAG_CROSS_USERS;
@@ -79,22 +74,67 @@
mRecentTasks = root.mService.getRecentTasks();
mKeepIntentExtra = (flags & FLAG_KEEP_INTENT_EXTRA) == FLAG_KEEP_INTENT_EXTRA;
- final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
- PooledLambda.__(Task.class));
- root.forAllLeafTasks(c, false);
- c.recycle();
+ if (root instanceof RootWindowContainer) {
+ ((RootWindowContainer) root).forAllDisplays(dc -> {
+ final Task focusedTask = dc.mFocusedApp != null ? dc.mFocusedApp.getTask() : null;
+ if (focusedTask != null) {
+ mTmpFocusedTasks.add(focusedTask);
+ }
+ processTaskInWindowContainer(dc);
+ });
+ } else {
+ final DisplayContent dc = root.getDisplayContent();
+ final Task focusedTask = dc != null
+ ? (dc.mFocusedApp != null ? dc.mFocusedApp.getTask() : null)
+ : null;
+ // May not be include focusedTask if root is DisplayArea.
+ final boolean rootContainsFocusedTask = focusedTask != null
+ && focusedTask.isDescendantOf(root);
+ if (rootContainsFocusedTask) {
+ mTmpFocusedTasks.add(focusedTask);
+ }
+ processTaskInWindowContainer(root);
+ }
+
+ final int visibleTaskCount = mTmpVisibleTasks.size();
+ for (int i = 0; i < mTmpFocusedTasks.size(); i++) {
+ final Task focusedTask = mTmpFocusedTasks.get(i);
+ final boolean containsFocusedTask = mTmpVisibleTasks.remove(focusedTask);
+ if (containsFocusedTask) {
+ // Put the visible focused task at the first position.
+ mTmpSortedTasks.add(focusedTask);
+ }
+ }
+ if (!mTmpVisibleTasks.isEmpty()) {
+ mTmpSortedTasks.addAll(mTmpVisibleTasks);
+ }
+ if (!mTmpInvisibleTasks.isEmpty()) {
+ mTmpSortedTasks.addAll(mTmpInvisibleTasks);
+ }
// Take the first {@param maxNum} tasks and create running task infos for them
- final Iterator<Task> iter = mTmpSortedSet.iterator();
- while (iter.hasNext()) {
- if (maxNum == 0) {
- break;
- }
-
- final Task task = iter.next();
- list.add(createRunningTaskInfo(task));
- maxNum--;
+ final int size = Math.min(maxNum, mTmpSortedTasks.size());
+ final long now = SystemClock.elapsedRealtime();
+ for (int i = 0; i < size; i++) {
+ final Task task = mTmpSortedTasks.get(i);
+ // Override the last active to current time for the visible tasks because the visible
+ // tasks can be considered to be currently active, the values are descending as
+ // the item order.
+ final long visibleActiveTime = i < visibleTaskCount ? now + size - i : -1;
+ list.add(createRunningTaskInfo(task, visibleActiveTime));
}
+
+ mTmpFocusedTasks.clear();
+ mTmpVisibleTasks.clear();
+ mTmpInvisibleTasks.clear();
+ mTmpSortedTasks.clear();
+ }
+
+ private void processTaskInWindowContainer(WindowContainer wc) {
+ final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
+ PooledLambda.__(Task.class));
+ wc.forAllLeafTasks(c, true);
+ c.recycle();
}
private void processTask(Task task) {
@@ -121,25 +161,20 @@
// home & recent tasks
return;
}
-
if (task.isVisible()) {
- // For the visible task, update the last active time so that it can be used to determine
- // the order of the tasks (it may not be set for newly created tasks)
- task.touchActiveTime();
- if (!task.isFocused()) {
- // TreeSet doesn't allow the same value and make sure this task is lower than the
- // focused one.
- task.lastActiveTime -= mTmpSortedSet.size();
- }
+ mTmpVisibleTasks.add(task);
+ } else {
+ mTmpInvisibleTasks.add(task);
}
-
- mTmpSortedSet.add(task);
}
/** Constructs a {@link RunningTaskInfo} from a given {@param task}. */
- private RunningTaskInfo createRunningTaskInfo(Task task) {
+ private RunningTaskInfo createRunningTaskInfo(Task task, long visibleActiveTime) {
final RunningTaskInfo rti = new RunningTaskInfo();
task.fillTaskInfo(rti, !mKeepIntentExtra);
+ if (visibleActiveTime > 0) {
+ rti.lastActiveTime = visibleActiveTime;
+ }
// Fill in some deprecated values
rti.id = rti.taskId;
return rti;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index e1ee045..5d53c20 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5458,7 +5458,23 @@
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
- parent.deliverNewIntentLocked(callingUid, destIntent, destGrants, srec.packageName);
+ boolean abort;
+ try {
+ abort = !mTaskSupervisor.checkStartAnyActivityPermission(destIntent,
+ parent.info, null /* resultWho */, -1 /* requestCode */, srec.getPid(),
+ callingUid, srec.info.packageName, null /* callingFeatureId */,
+ false /* ignoreTargetSecurity */, false /* launchingInTask */, srec.app,
+ null /* resultRecord */, null /* resultRootTask */);
+ } catch (SecurityException e) {
+ abort = true;
+ }
+ if (abort) {
+ android.util.EventLog.writeEvent(0x534e4554, "238605611", callingUid, "");
+ foundParentInTask = false;
+ } else {
+ parent.deliverNewIntentLocked(callingUid, destIntent, destGrants,
+ srec.packageName);
+ }
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 911fb6a..08c2c6e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -1301,6 +1301,21 @@
}
@Test
+ public void testA11yCrossUserEventNotSent() throws Exception {
+ final Notification n = new Builder(getContext(), "test")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
+ int userId = mUser.getIdentifier() + 1;
+ StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+ mPid, n, UserHandle.of(userId), null, System.currentTimeMillis());
+ NotificationRecord r = new NotificationRecord(getContext(), sbn,
+ new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
+ }
+
+ @Test
public void testLightsScreenOn() {
mService.mScreenOn = true;
NotificationRecord r = getLightsNotification();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 480ad11..535183d 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -7509,6 +7509,43 @@
}
@Test
+ public void testAddAutomaticZenRule_systemCallTakesPackageFromOwner() throws Exception {
+ mService.isSystemUid = true;
+ ZenModeHelper mockZenModeHelper = mock(ZenModeHelper.class);
+ when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt()))
+ .thenReturn(true);
+ mService.setZenHelper(mockZenModeHelper);
+ ComponentName owner = new ComponentName("android", "ProviderName");
+ ZenPolicy zenPolicy = new ZenPolicy.Builder().allowAlarms(true).build();
+ boolean isEnabled = true;
+ AutomaticZenRule rule = new AutomaticZenRule("test", owner, owner, mock(Uri.class),
+ zenPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, isEnabled);
+ mBinderService.addAutomaticZenRule(rule, "com.android.settings");
+
+ // verify that zen mode helper gets passed in a package name of "android"
+ verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString());
+ }
+
+ @Test
+ public void testAddAutomaticZenRule_nonSystemCallTakesPackageFromArg() throws Exception {
+ mService.isSystemUid = false;
+ ZenModeHelper mockZenModeHelper = mock(ZenModeHelper.class);
+ when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt()))
+ .thenReturn(true);
+ mService.setZenHelper(mockZenModeHelper);
+ ComponentName owner = new ComponentName("android", "ProviderName");
+ ZenPolicy zenPolicy = new ZenPolicy.Builder().allowAlarms(true).build();
+ boolean isEnabled = true;
+ AutomaticZenRule rule = new AutomaticZenRule("test", owner, owner, mock(Uri.class),
+ zenPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, isEnabled);
+ mBinderService.addAutomaticZenRule(rule, "another.package");
+
+ // verify that zen mode helper gets passed in the package name from the arg, not the owner
+ verify(mockZenModeHelper).addAutomaticZenRule(
+ eq("another.package"), eq(rule), anyString());
+ }
+
+ @Test
public void testAreNotificationsEnabledForPackage() throws Exception {
mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(),
mUid);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 4550b56..2ccdcaa 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -1672,6 +1672,36 @@
}
@Test
+ public void testAddAutomaticZenRule_claimedSystemOwner() {
+ // Make sure anything that claims to have a "system" owner but not actually part of the
+ // system package still gets limited on number of rules
+ for (int i = 0; i < RULE_LIMIT_PER_PACKAGE; i++) {
+ ScheduleInfo si = new ScheduleInfo();
+ si.startHour = i;
+ AutomaticZenRule zenRule = new AutomaticZenRule("name" + i,
+ new ComponentName("android", "ScheduleConditionProvider" + i),
+ null, // configuration activity
+ ZenModeConfig.toScheduleConditionId(si),
+ new ZenPolicy.Builder().build(),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+ assertNotNull(id);
+ }
+ try {
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ new ComponentName("android", "ScheduleConditionProviderFinal"),
+ null, // configuration activity
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ new ZenPolicy.Builder().build(),
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id = mZenModeHelperSpy.addAutomaticZenRule("pkgname", zenRule, "test");
+ fail("allowed too many rules to be created");
+ } catch (IllegalArgumentException e) {
+ // yay
+ }
+ }
+
+ @Test
public void testAddAutomaticZenRule_CA() {
AutomaticZenRule zenRule = new AutomaticZenRule("name",
null,
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index 33b2366..13fc61c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -61,55 +61,6 @@
}
@Test
- public void testCollectTasksByLastActiveTime() {
- // Create a number of stacks with tasks (of incrementing active time)
- final ArrayList<DisplayContent> displays = new ArrayList<>();
- final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
- displays.add(display);
-
- final int numStacks = 2;
- for (int stackIndex = 0; stackIndex < numStacks; stackIndex++) {
- final Task stack = new TaskBuilder(mSupervisor)
- .setDisplay(display)
- .setOnTop(false)
- .build();
- }
-
- final int numTasks = 10;
- int activeTime = 0;
- final List<Task> rootTasks = new ArrayList<>();
- display.getDefaultTaskDisplayArea().forAllRootTasks(task -> {
- rootTasks.add(task);
- }, false /* traverseTopToBottom */);
- for (int i = 0; i < numTasks; i++) {
- final Task task =
- createTask(rootTasks.get(i % numStacks), ".Task" + i, i, activeTime++, null);
- doReturn(false).when(task).isVisible();
- }
-
- // Ensure that the latest tasks were returned in order of decreasing last active time,
- // collected from all tasks across all the stacks
- final int numFetchTasks = 5;
- ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
- mRunningTasks.getTasks(5, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS, mRootWindowContainer,
- -1 /* callingUid */, PROFILE_IDS);
- assertThat(tasks).hasSize(numFetchTasks);
- for (int i = 0; i < numFetchTasks; i++) {
- assertEquals(numTasks - i - 1, tasks.get(i).id);
- }
-
- // Ensure that requesting more than the total number of tasks only returns the subset
- // and does not crash
- tasks.clear();
- mRunningTasks.getTasks(100, tasks, FLAG_ALLOWED | FLAG_CROSS_USERS,
- mRootWindowContainer, -1 /* callingUid */, PROFILE_IDS);
- assertThat(tasks).hasSize(numTasks);
- for (int i = 0; i < numTasks; i++) {
- assertEquals(numTasks - i - 1, tasks.get(i).id);
- }
- }
-
- @Test
public void testTaskInfo_expectNoExtrasByDefault() {
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
final int numTasks = 10;
@@ -120,7 +71,7 @@
.build();
final Bundle data = new Bundle();
data.putInt("key", 100);
- createTask(stack, ".Task" + i, i, i, data);
+ createTask(stack, ".Task" + i, i, data);
}
final int numFetchTasks = 5;
@@ -145,7 +96,7 @@
.build();
final Bundle data = new Bundle();
data.putInt("key", 100);
- createTask(stack, ".Task" + i, i, i, data);
+ createTask(stack, ".Task" + i, i, data);
}
final int numFetchTasks = 5;
@@ -162,46 +113,63 @@
}
@Test
- public void testUpdateLastActiveTimeOfVisibleTasks() {
+ public void testGetTasksSortByFocusAndVisibility() {
final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2500).build();
+ final Task stack = new TaskBuilder(mSupervisor)
+ .setDisplay(display)
+ .setOnTop(true)
+ .build();
+
final int numTasks = 10;
final ArrayList<Task> tasks = new ArrayList<>();
for (int i = 0; i < numTasks; i++) {
- final Task task = createTask(null, ".Task" + i, i, i, null);
+ final Task task = createTask(stack, ".Task" + i, i, null);
doReturn(false).when(task).isVisible();
tasks.add(task);
}
- final Task visibleTask = tasks.get(0);
- doReturn(true).when(visibleTask).isVisible();
-
- final Task focusedTask = tasks.get(1);
+ final Task focusedTask = tasks.get(numTasks - 1);
doReturn(true).when(focusedTask).isVisible();
- doReturn(true).when(focusedTask).isFocused();
+ display.mFocusedApp = focusedTask.getTopNonFinishingActivity();
- // Ensure that the last active time of visible tasks were updated while the focused one had
- // the largest last active time.
+ final Task visibleTaskTop = tasks.get(numTasks - 2);
+ doReturn(true).when(visibleTaskTop).isVisible();
+
+ final Task visibleTaskBottom = tasks.get(numTasks - 3);
+ doReturn(true).when(visibleTaskBottom).isVisible();
+
+ // Ensure that the focused Task is on top, visible tasks below, then invisible tasks.
final int numFetchTasks = 5;
final ArrayList<RunningTaskInfo> fetchTasks = new ArrayList<>();
mRunningTasks.getTasks(numFetchTasks, fetchTasks,
FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, mRootWindowContainer,
-1 /* callingUid */, PROFILE_IDS);
assertThat(fetchTasks).hasSize(numFetchTasks);
- assertEquals(fetchTasks.get(0).id, focusedTask.mTaskId);
- assertEquals(fetchTasks.get(1).id, visibleTask.mTaskId);
+ for (int i = 0; i < numFetchTasks; i++) {
+ assertEquals(numTasks - i - 1, fetchTasks.get(i).id);
+ }
+
+ // Ensure that requesting more than the total number of tasks only returns the subset
+ // and does not crash
+ fetchTasks.clear();
+ mRunningTasks.getTasks(100, fetchTasks,
+ FLAG_ALLOWED | FLAG_CROSS_USERS | FLAG_KEEP_INTENT_EXTRA, mRootWindowContainer,
+ -1 /* callingUid */, PROFILE_IDS);
+ assertThat(fetchTasks).hasSize(numTasks);
+ for (int i = 0; i < numTasks; i++) {
+ assertEquals(numTasks - i - 1, fetchTasks.get(i).id);
+ }
}
/**
- * Create a task with a single activity in it, with the given last active time.
+ * Create a task with a single activity in it.
*/
- private Task createTask(Task stack, String className, int taskId,
- int lastActiveTime, Bundle extras) {
+ private Task createTask(Task stack, String className, int taskId, Bundle extras) {
final Task task = new TaskBuilder(mAtm.mTaskSupervisor)
.setComponent(new ComponentName(mContext.getPackageName(), className))
.setTaskId(taskId)
.setParentTaskFragment(stack)
.build();
- task.lastActiveTime = lastActiveTime;
final ActivityRecord activity = new ActivityBuilder(mAtm)
.setTask(task)
.setComponent(new ComponentName(mContext.getPackageName(), ".TaskActivity"))
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index e0f5b20..983d82b 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1269,7 +1269,7 @@
if (service != null) {
try {
return service.getPhoneAccountsSupportingScheme(uriScheme,
- mContext.getOpPackageName());
+ mContext.getOpPackageName()).getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsSupportingScheme", e);
}
@@ -1312,7 +1312,7 @@
if (service != null) {
try {
return service.getSelfManagedPhoneAccounts(mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag()).getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getSelfManagedPhoneAccounts()", e);
}
@@ -1340,7 +1340,7 @@
if (service != null) {
try {
return service.getOwnSelfManagedPhoneAccounts(mContext.getOpPackageName(),
- mContext.getAttributionTag());
+ mContext.getAttributionTag()).getList();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1366,7 +1366,7 @@
if (service != null) {
try {
return service.getCallCapablePhoneAccounts(includeDisabledAccounts,
- mContext.getOpPackageName(), mContext.getAttributionTag());
+ mContext.getOpPackageName(), mContext.getAttributionTag()).getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getCallCapablePhoneAccounts("
+ includeDisabledAccounts + ")", e);
@@ -1390,7 +1390,7 @@
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getPhoneAccountsForPackage(mContext.getPackageName());
+ return service.getPhoneAccountsForPackage(mContext.getPackageName()).getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getPhoneAccountsForPackage", e);
}
@@ -1450,7 +1450,7 @@
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getAllPhoneAccounts();
+ return service.getAllPhoneAccounts().getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccounts", e);
}
@@ -1469,7 +1469,7 @@
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getAllPhoneAccountHandles();
+ return service.getAllPhoneAccountHandles().getList();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getAllPhoneAccountHandles", e);
}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 37403a8..74b5545 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -24,6 +24,7 @@
import android.os.Bundle;
import android.os.UserHandle;
import android.telecom.PhoneAccount;
+import android.content.pm.ParceledListSlice;
/**
* Interface used to interact with Telecom. Mostly this is used by TelephonyManager for passing
@@ -57,31 +58,31 @@
/**
* @see TelecomServiceImpl#getCallCapablePhoneAccounts
*/
- List<PhoneAccountHandle> getCallCapablePhoneAccounts(
+ ParceledListSlice<PhoneAccountHandle> getCallCapablePhoneAccounts(
boolean includeDisabledAccounts, String callingPackage, String callingFeatureId);
/**
* @see TelecomServiceImpl#getSelfManagedPhoneAccounts
*/
- List<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage,
+ ParceledListSlice<PhoneAccountHandle> getSelfManagedPhoneAccounts(String callingPackage,
String callingFeatureId);
/**
* @see TelecomServiceImpl#getOwnSelfManagedPhoneAccounts
*/
- List<PhoneAccountHandle> getOwnSelfManagedPhoneAccounts(String callingPackage,
+ ParceledListSlice<PhoneAccountHandle> getOwnSelfManagedPhoneAccounts(String callingPackage,
String callingFeatureId);
/**
* @see TelecomManager#getPhoneAccountsSupportingScheme
*/
- List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme,
+ ParceledListSlice<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme,
String callingPackage);
/**
* @see TelecomManager#getPhoneAccountsForPackage
*/
- List<PhoneAccountHandle> getPhoneAccountsForPackage(in String packageName);
+ ParceledListSlice<PhoneAccountHandle> getPhoneAccountsForPackage(in String packageName);
/**
* @see TelecomManager#getPhoneAccount
@@ -96,12 +97,12 @@
/**
* @see TelecomManager#getAllPhoneAccounts
*/
- List<PhoneAccount> getAllPhoneAccounts();
+ ParceledListSlice<PhoneAccount> getAllPhoneAccounts();
/**
* @see TelecomManager#getAllPhoneAccountHandles
*/
- List<PhoneAccountHandle> getAllPhoneAccountHandles();
+ ParceledListSlice<PhoneAccountHandle> getAllPhoneAccountHandles();
/**
* @see TelecomServiceImpl#getSimCallManager
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index bb0522c..bd993f2 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -8478,7 +8478,12 @@
*
* Used to trade privacy/security against potentially reduced carrier coverage for some
* carriers.
+ *
+ * @deprecated Future versions of Android will disallow carriers from hiding this toggle
+ * because disabling 2g is a security feature that users should always have access to at
+ * their discretion.
*/
+ @Deprecated
public static final String KEY_HIDE_ENABLE_2G = "hide_enable_2g_bool";
/**
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index e0145e6..c2b65f8 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -1092,6 +1092,11 @@
if (!TextUtils.isEmpty(simOperator)) {
for (NoEmsSupportConfig currentConfig : mNoEmsSupportConfigList) {
+ if (currentConfig == null) {
+ Rlog.w("SmsMessage", "hasEmsSupport currentConfig is null");
+ continue;
+ }
+
if (simOperator.startsWith(currentConfig.mOperatorNumber) &&
(TextUtils.isEmpty(currentConfig.mGid1) ||
(!TextUtils.isEmpty(currentConfig.mGid1) &&
@@ -1155,18 +1160,21 @@
private static boolean mIsNoEmsSupportConfigListLoaded = false;
private static boolean isNoEmsSupportConfigListExisted() {
- if (!mIsNoEmsSupportConfigListLoaded) {
- Resources r = Resources.getSystem();
- if (r != null) {
- String[] listArray = r.getStringArray(
- com.android.internal.R.array.no_ems_support_sim_operators);
- if ((listArray != null) && (listArray.length > 0)) {
- mNoEmsSupportConfigList = new NoEmsSupportConfig[listArray.length];
- for (int i=0; i<listArray.length; i++) {
- mNoEmsSupportConfigList[i] = new NoEmsSupportConfig(listArray[i].split(";"));
+ synchronized (SmsMessage.class) {
+ if (!mIsNoEmsSupportConfigListLoaded) {
+ Resources r = Resources.getSystem();
+ if (r != null) {
+ String[] listArray = r.getStringArray(
+ com.android.internal.R.array.no_ems_support_sim_operators);
+ if ((listArray != null) && (listArray.length > 0)) {
+ mNoEmsSupportConfigList = new NoEmsSupportConfig[listArray.length];
+ for (int i = 0; i < listArray.length; i++) {
+ mNoEmsSupportConfigList[i] = new NoEmsSupportConfig(
+ listArray[i].split(";"));
+ }
}
+ mIsNoEmsSupportConfigListLoaded = true;
}
- mIsNoEmsSupportConfigListLoaded = true;
}
}
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index be233b8..bccb6ef 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -425,8 +425,8 @@
}
}
- private IImsRcsFeature createRcsFeatureInternal(int slotId, int subI) {
- RcsFeature f = createRcsFeatureForSubscription(slotId, subI);
+ private IImsRcsFeature createRcsFeatureInternal(int slotId, int subId) {
+ RcsFeature f = createRcsFeatureForSubscription(slotId, subId);
if (f != null) {
f.setDefaultExecutor(mExecutor);
setupFeature(f, slotId, ImsFeature.FEATURE_RCS);
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index f5b158f..a42327b 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -394,10 +394,12 @@
@VisibleForTesting
public void addImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) {
try {
- // If we have just connected, send queued status.
- c.notifyImsFeatureStatus(getFeatureState());
- // Add the callback if the callback completes successfully without a RemoteException.
- mStatusCallbacks.register(c);
+ synchronized (mStatusCallbacks) {
+ // Add the callback if the callback completes successfully without a RemoteException
+ mStatusCallbacks.register(c);
+ // If we have just connected, send queued status.
+ c.notifyImsFeatureStatus(getFeatureState());
+ }
} catch (RemoteException e) {
Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
}
@@ -409,7 +411,9 @@
*/
@VisibleForTesting
public void removeImsFeatureStatusCallback(@NonNull IImsFeatureStatusCallback c) {
- mStatusCallbacks.unregister(c);
+ synchronized (mStatusCallbacks) {
+ mStatusCallbacks.unregister(c);
+ }
}
/**
diff --git a/tools/locked_region_code_injection/Android.bp b/tools/locked_region_code_injection/Android.bp
index 6efd1f6..ff1f8e2 100644
--- a/tools/locked_region_code_injection/Android.bp
+++ b/tools/locked_region_code_injection/Android.bp
@@ -16,6 +16,6 @@
"asm-commons-9.2",
"asm-tree-9.2",
"asm-analysis-9.2",
- "guava-21.0",
+ "guava",
],
}
diff --git a/tools/traceinjection/Android.bp b/tools/traceinjection/Android.bp
index 39d1b1c..bb32df6 100644
--- a/tools/traceinjection/Android.bp
+++ b/tools/traceinjection/Android.bp
@@ -16,7 +16,7 @@
"asm-commons-9.2",
"asm-tree-9.2",
"asm-analysis-9.2",
- "guava-21.0",
+ "guava",
],
}