summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-11-03 22:41:10 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-11-03 22:41:10 +0000
commit1a73f73ac9bdbb5549564f5aace79afea9f162ea (patch)
treedc3a4c67867af7745558125afd006f168956066f
parent99c367e548ccb3a8101d784e73d3ae2f5a16a0e6 (diff)
parent250714c67ba9d2029bc88284672949a87b243b9a (diff)
downloadbase-1a73f73ac9bdbb5549564f5aace79afea9f162ea.tar.gz
Snap for 4431872 from 250714c67ba9d2029bc88284672949a87b243b9a to oc-m2-releaseandroid-8.1.0_r2
Change-Id: I959e83ca9924df486c7e27876a5a354a8d46df9e
-rw-r--r--core/java/android/app/Activity.java14
-rw-r--r--core/java/android/app/INotificationManager.aidl1
-rw-r--r--core/java/android/content/pm/ActivityInfo.java31
-rw-r--r--core/java/android/content/res/ResourcesImpl.java66
-rw-r--r--core/java/com/android/internal/app/NightDisplayController.java17
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java16
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java20
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java12
-rw-r--r--services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java74
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java2
-rw-r--r--tools/aapt2/compile/InlineXmlFormatParser.cpp4
-rw-r--r--tools/aapt2/compile/InlineXmlFormatParser_test.cpp43
12 files changed, 214 insertions, 86 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 26f5ba130b7b..2c04f8ff9548 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,8 +16,6 @@
package android.app;
-import static android.os.Build.VERSION_CODES.O_MR1;
-
import static java.lang.Character.MIN_VALUE;
import android.annotation.CallSuper;
@@ -990,18 +988,6 @@ public class Activity extends ContextThemeWrapper
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
-
- if (getApplicationInfo().targetSdkVersion >= O_MR1 && mActivityInfo.isFixedOrientation()) {
- final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
- final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
- ta.recycle();
-
- if (isTranslucentOrFloating) {
- throw new IllegalStateException(
- "Only fullscreen opaque activities can request orientation");
- }
- }
-
if (mLastNonConfigurationInstances != null) {
mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 08821bebd57e..0c80deaba910 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -135,6 +135,7 @@ interface INotificationManager
void setNotificationPolicy(String pkg, in NotificationManager.Policy policy);
boolean isNotificationPolicyAccessGrantedForPackage(String pkg);
void setNotificationPolicyAccessGranted(String pkg, boolean granted);
+ void setNotificationPolicyAccessGrantedForUser(String pkg, int userId, boolean granted);
AutomaticZenRule getAutomaticZenRule(String id);
List<ZenModeConfig.ZenRule> getZenRules();
String addAutomaticZenRule(in AutomaticZenRule automaticZenRule);
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 93338bb5b025..e0c3f75e223e 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -20,7 +20,6 @@ import android.annotation.IntDef;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Configuration.NativeConfig;
-import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Printer;
@@ -454,7 +453,6 @@ public class ActivityInfo extends ComponentInfo
*/
public static final int FLAG_TURN_SCREEN_ON = 0x1000000;
-
/**
* @hide Bit in {@link #flags}: If set, this component will only be seen
* by the system user. Only works with broadcast receivers. Set from the
@@ -993,20 +991,12 @@ public class ActivityInfo extends ComponentInfo
* Returns true if the activity's orientation is fixed.
* @hide
*/
- public boolean isFixedOrientation() {
+ boolean isFixedOrientation() {
return isFixedOrientationLandscape() || isFixedOrientationPortrait()
|| screenOrientation == SCREEN_ORIENTATION_LOCKED;
}
/**
- * Returns true if the specified orientation is considered fixed.
- * @hide
- */
- static public boolean isFixedOrientation(int orientation) {
- return isFixedOrientationLandscape(orientation) || isFixedOrientationPortrait(orientation);
- }
-
- /**
* Returns true if the activity's orientation is fixed to landscape.
* @hide
*/
@@ -1185,25 +1175,6 @@ public class ActivityInfo extends ComponentInfo
dest.writeFloat(maxAspectRatio);
}
- /**
- * Determines whether the {@link Activity} is considered translucent or floating.
- * @hide
- */
- public static boolean isTranslucentOrFloating(TypedArray attributes) {
- final boolean isTranslucent =
- attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent,
- false);
- final boolean isSwipeToDismiss = !attributes.hasValue(
- com.android.internal.R.styleable.Window_windowIsTranslucent)
- && attributes.getBoolean(
- com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
- final boolean isFloating =
- attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating,
- false);
-
- return isFloating || isTranslucent || isSwipeToDismiss;
- }
-
public static final Parcelable.Creator<ActivityInfo> CREATOR
= new Parcelable.Creator<ActivityInfo>() {
public ActivityInfo createFromParcel(Parcel source) {
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 386239cf4f93..3239212adf66 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -49,6 +49,8 @@ import android.util.TypedValue;
import android.util.Xml;
import android.view.DisplayAdjustments;
+import com.android.internal.util.GrowingArrayUtils;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -117,6 +119,13 @@ public class ResourcesImpl {
private final ConfigurationBoundResourceCache<StateListAnimator> mStateListAnimatorCache =
new ConfigurationBoundResourceCache<>();
+ // A stack of all the resourceIds already referenced when parsing a resource. This is used to
+ // detect circular references in the xml.
+ // Using a ThreadLocal variable ensures that we have different stacks for multiple parallel
+ // calls to ResourcesImpl
+ private final ThreadLocal<LookupStack> mLookupStack =
+ ThreadLocal.withInitial(() -> new LookupStack());
+
/** Size of the cyclical cache used to map XML files to blocks. */
private static final int XML_BLOCK_CACHE_SIZE = 4;
@@ -784,19 +793,29 @@ public class ResourcesImpl {
final Drawable dr;
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, file);
+ LookupStack stack = mLookupStack.get();
try {
- if (file.endsWith(".xml")) {
- final XmlResourceParser rp = loadXmlResourceParser(
- file, id, value.assetCookie, "drawable");
- dr = Drawable.createFromXmlForDensity(wrapper, rp, density, theme);
- rp.close();
- } else {
- final InputStream is = mAssets.openNonAsset(
- value.assetCookie, file, AssetManager.ACCESS_STREAMING);
- dr = Drawable.createFromResourceStream(wrapper, value, is, file, null);
- is.close();
+ // Perform a linear search to check if we have already referenced this resource before.
+ if (stack.contains(id)) {
+ throw new Exception("Recursive reference in drawable");
}
- } catch (Exception | StackOverflowError e) {
+ stack.push(id);
+ try {
+ if (file.endsWith(".xml")) {
+ final XmlResourceParser rp = loadXmlResourceParser(
+ file, id, value.assetCookie, "drawable");
+ dr = Drawable.createFromXmlForDensity(wrapper, rp, density, theme);
+ rp.close();
+ } else {
+ final InputStream is = mAssets.openNonAsset(
+ value.assetCookie, file, AssetManager.ACCESS_STREAMING);
+ dr = Drawable.createFromResourceStream(wrapper, value, is, file, null);
+ is.close();
+ }
+ } finally {
+ stack.pop();
+ }
+ } catch (Exception e) {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
final NotFoundException rnf = new NotFoundException(
"File " + file + " from drawable resource ID #0x" + Integer.toHexString(id));
@@ -1377,4 +1396,29 @@ public class ResourcesImpl {
}
}
}
+
+ private static class LookupStack {
+
+ // Pick a reasonable default size for the array, it is grown as needed.
+ private int[] mIds = new int[4];
+ private int mSize = 0;
+
+ public void push(int id) {
+ mIds = GrowingArrayUtils.append(mIds, mSize, id);
+ mSize++;
+ }
+
+ public boolean contains(int id) {
+ for (int i = 0; i < mSize; i++) {
+ if (mIds[i] == id) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void pop() {
+ mSize--;
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/NightDisplayController.java b/core/java/com/android/internal/app/NightDisplayController.java
index d581777ba5bf..e0e15c818a02 100644
--- a/core/java/com/android/internal/app/NightDisplayController.java
+++ b/core/java/com/android/internal/app/NightDisplayController.java
@@ -25,6 +25,7 @@ import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
+import android.os.SystemProperties;
import android.provider.Settings.Secure;
import android.provider.Settings.System;
import android.util.Slog;
@@ -100,6 +101,12 @@ public final class NightDisplayController {
*/
public static final int COLOR_MODE_SATURATED = 2;
+ /**
+ * See com.android.server.display.DisplayTransformManager.
+ */
+ private static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
+ private static final String PERSISTENT_PROPERTY_NATIVE_MODE = "persist.sys.sf.native_mode";
+
private final Context mContext;
private final int mUserId;
@@ -334,9 +341,15 @@ public final class NightDisplayController {
*/
public int getColorMode() {
final int colorMode = System.getIntForUser(mContext.getContentResolver(),
- System.DISPLAY_COLOR_MODE, COLOR_MODE_BOOSTED, mUserId);
+ System.DISPLAY_COLOR_MODE, -1, mUserId);
if (colorMode < COLOR_MODE_NATURAL || colorMode > COLOR_MODE_SATURATED) {
- return COLOR_MODE_BOOSTED;
+ // There still might be a legacy system property controlling color mode that we need to
+ // respect.
+ if ("1".equals(SystemProperties.get(PERSISTENT_PROPERTY_NATIVE_MODE))) {
+ return COLOR_MODE_SATURATED;
+ }
+ return "1.0".equals(SystemProperties.get(PERSISTENT_PROPERTY_SATURATION))
+ ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED;
}
return colorMode;
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 4d98f19f79b9..be281df3a445 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -74,7 +74,6 @@ import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Build.VERSION_CODES.O;
-import static android.os.Build.VERSION_CODES.O_MR1;
import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.WindowManagerPolicy.NAV_BAR_LEFT;
@@ -897,7 +896,15 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
Entry ent = AttributeCache.instance().get(packageName,
realTheme, com.android.internal.R.styleable.Window, userId);
- fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);
+ final boolean translucent = ent != null && (ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsTranslucent, false)
+ || (!ent.array.hasValue(
+ com.android.internal.R.styleable.Window_windowIsTranslucent)
+ && ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowSwipeToDismiss,
+ false)));
+ fullscreen = ent != null && !ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsFloating, false) && !translucent;
noDisplay = ent != null && ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
@@ -2184,11 +2191,6 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
}
void setRequestedOrientation(int requestedOrientation) {
- if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen
- && appInfo.targetSdkVersion >= O_MR1) {
- throw new IllegalStateException("Only fullscreen activities can request orientation");
- }
-
final int displayId = getDisplayId();
final Configuration displayConfig =
mStackSupervisor.getDisplayOverrideConfiguration(displayId);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 842ee9135e33..566e5f52625e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1196,7 +1196,6 @@ public class NotificationManagerService extends SystemService {
mAccessibilityManager = am;
}
-
// TODO: All tests should use this init instead of the one-off setters above.
@VisibleForTesting
void init(Looper looper, IPackageManager packageManager,
@@ -2764,19 +2763,25 @@ public class NotificationManagerService extends SystemService {
@Override
public void setNotificationPolicyAccessGranted(String pkg, boolean granted)
throws RemoteException {
+ setNotificationPolicyAccessGrantedForUser(
+ pkg, getCallingUserHandle().getIdentifier(), granted);
+ }
+
+ @Override
+ public void setNotificationPolicyAccessGrantedForUser(
+ String pkg, int userId, boolean granted) {
checkCallerIsSystemOrShell();
final long identity = Binder.clearCallingIdentity();
try {
if (!mActivityManager.isLowRamDevice()) {
mConditionProviders.setPackageOrComponentEnabled(
- pkg, getCallingUserHandle().getIdentifier(), true, granted);
+ pkg, userId, true, granted);
getContext().sendBroadcastAsUser(new Intent(
NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
.setPackage(pkg)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
- getCallingUserHandle(), null);
-
+ UserHandle.of(userId), null);
savePolicyFile();
}
} finally {
@@ -2871,11 +2876,10 @@ public class NotificationManagerService extends SystemService {
userId, true, granted);
getContext().sendBroadcastAsUser(new Intent(
- NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
-
+ NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
.setPackage(listener.getPackageName())
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
- getCallingUserHandle(), null);
+ UserHandle.of(userId), null);
savePolicyFile();
}
@@ -2901,7 +2905,7 @@ public class NotificationManagerService extends SystemService {
NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
.setPackage(assistant.getPackageName())
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
- getCallingUserHandle(), null);
+ UserHandle.of(userId), null);
savePolicyFile();
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 0a7d1c1d3460..7b240c21a3a3 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -22,7 +22,6 @@ import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
-import static android.os.Build.VERSION_CODES.O_MR1;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
@@ -74,8 +73,6 @@ import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
-import static android.os.Build.VERSION_CODES.O;
-
class AppTokenList extends ArrayList<AppWindowToken> {
}
@@ -1309,15 +1306,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
*/
@Override
int getOrientation(int candidate) {
- // We do not allow non-fullscreen apps to influence orientation starting in O-MR1. While we
- // do throw an exception in {@link Activity#onCreate} and
- // {@link Activity#setRequestedOrientation}, we also ignore the orientation here so that
- // other calculations aren't affected.
- if (!fillsParent() && mTargetSdk >= O_MR1) {
- // Can't specify orientation if app doesn't fill parent.
- return SCREEN_ORIENTATION_UNSET;
- }
-
if (candidate == SCREEN_ORIENTATION_BEHIND) {
// Allow app to specify orientation regardless of its visibility state if the current
// candidate want us to use orientation behind. I.e. the visible app on-top of this one
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 7ea42daa617b..0c3f2d508e07 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -24,6 +24,7 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
@@ -38,6 +39,7 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -67,6 +69,7 @@ import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
+import android.testing.TestableContext;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArrayMap;
@@ -108,7 +111,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
private IPackageManager mPackageManager;
@Mock
private PackageManager mPackageManagerClient;
- private Context mContext = getContext();
+ private TestableContext mContext = spy(getContext());
private final String PKG = mContext.getPackageName();
private TestableLooper mTestableLooper;
@Mock
@@ -169,12 +172,14 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mTestableLooper = TestableLooper.get(this);
mHandler = mNotificationManagerService.new WorkerHandler(mTestableLooper.getLooper());
// MockPackageManager - default returns ApplicationInfo with matching calling UID
+ mContext.setMockPackageManager(mPackageManagerClient);
final ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.uid = mUid;
when(mPackageManager.getApplicationInfo(anyString(), anyInt(), anyInt()))
.thenReturn(applicationInfo);
when(mPackageManagerClient.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
.thenReturn(applicationInfo);
+ when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
final LightsManager mockLightsManager = mock(LightsManager.class);
when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
@@ -222,6 +227,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mBinderService.createNotificationChannels(
PKG, new ParceledListSlice(Arrays.asList(mTestNotificationChannel)));
+ assertNotNull(mBinderService.getNotificationChannel(PKG, TEST_CHANNEL_ID));
}
@After
@@ -1311,6 +1317,72 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
}
@Test
+ public void testSetListenerAccessForUser() throws Exception {
+ UserHandle user = UserHandle.of(10);
+ ComponentName c = ComponentName.unflattenFromString("package/Component");
+ try {
+ mBinderService.setNotificationListenerAccessGrantedForUser(
+ c, user.getIdentifier(), true);
+ } catch (SecurityException e) {
+ if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
+ throw e;
+ }
+ }
+
+ verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
+ verify(mListeners, times(1)).setPackageOrComponentEnabled(
+ c.flattenToString(), user.getIdentifier(), true, true);
+ verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
+ c.flattenToString(), user.getIdentifier(), false, true);
+ verify(mAssistants, never()).setPackageOrComponentEnabled(
+ any(), anyInt(), anyBoolean(), anyBoolean());
+ }
+
+ @Test
+ public void testSetAssistantAccessForUser() throws Exception {
+ UserHandle user = UserHandle.of(10);
+ ComponentName c = ComponentName.unflattenFromString("package/Component");
+ try {
+ mBinderService.setNotificationAssistantAccessGrantedForUser(
+ c, user.getIdentifier(), true);
+ } catch (SecurityException e) {
+ if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
+ throw e;
+ }
+ }
+
+ verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
+ verify(mAssistants, times(1)).setPackageOrComponentEnabled(
+ c.flattenToString(), user.getIdentifier(), true, true);
+ verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
+ c.flattenToString(), user.getIdentifier(), false, true);
+ verify(mListeners, never()).setPackageOrComponentEnabled(
+ any(), anyInt(), anyBoolean(), anyBoolean());
+ }
+
+ @Test
+ public void testSetDndAccessForUser() throws Exception {
+ UserHandle user = UserHandle.of(10);
+ ComponentName c = ComponentName.unflattenFromString("package/Component");
+ try {
+ mBinderService.setNotificationPolicyAccessGrantedForUser(
+ c.getPackageName(), user.getIdentifier(), true);
+ } catch (SecurityException e) {
+ if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
+ throw e;
+ }
+ }
+
+ verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
+ verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
+ c.getPackageName(), user.getIdentifier(), true, true);
+ verify(mAssistants, never()).setPackageOrComponentEnabled(
+ any(), anyInt(), anyBoolean(), anyBoolean());
+ verify(mListeners, never()).setPackageOrComponentEnabled(
+ any(), anyInt(), anyBoolean(), anyBoolean());
+ }
+
+ @Test
public void testSetListenerAccess() throws Exception {
ComponentName c = ComponentName.unflattenFromString("package/Component");
try {
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 9ad7addab858..25d700f97805 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -193,7 +193,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
token.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
token.setFillsParent(false);
- // Can specify orientation if app doesn't fill parent. Allowed for SDK <= 25.
+ // Can specify orientation if doesn't fill parent.
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, token.getOrientation());
token.setFillsParent(true);
diff --git a/tools/aapt2/compile/InlineXmlFormatParser.cpp b/tools/aapt2/compile/InlineXmlFormatParser.cpp
index 857cdd5365a0..73a90da6baf0 100644
--- a/tools/aapt2/compile/InlineXmlFormatParser.cpp
+++ b/tools/aapt2/compile/InlineXmlFormatParser.cpp
@@ -146,6 +146,10 @@ bool InlineXmlFormatParser::Consume(IAaptContext* context, xml::XmlResource* doc
} else {
new_doc->root.reset(static_cast<xml::Element*>(child.release()));
new_doc->root->parent = nullptr;
+ // Copy down the namespace declarations
+ new_doc->root->namespace_decls = doc->root->namespace_decls;
+ // Recurse for nested inlines
+ Consume(context, new_doc.get());
}
}
diff --git a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
index de7739ada407..a4c602c29b86 100644
--- a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
+++ b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
@@ -137,4 +137,47 @@ TEST(InlineXmlFormatParserTest, ExtractTwoXmlResources) {
EXPECT_THAT(extracted_doc_drawable->root->name, StrEq("vector"));
}
+TEST(InlineXmlFormatParserTest, ExtractNestedXmlResources) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+ <base_root xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="inline_xml">
+ <inline_root>
+ <aapt:attr name="nested_inline_xml">
+ <nested_inline_root/>
+ </aapt:attr>
+ <aapt:attr name="another_nested_inline_xml">
+ <root/>
+ </aapt:attr>
+ </inline_root>
+ </aapt:attr>
+ <aapt:attr name="turtles">
+ <root1>
+ <aapt:attr name="all">
+ <root2>
+ <aapt:attr name="the">
+ <root3>
+ <aapt:attr name="way">
+ <root4>
+ <aapt:attr name="down">
+ <root5/>
+ </aapt:attr>
+ </root4>
+ </aapt:attr>
+ </root3>
+ </aapt:attr>
+ </root2>
+ </aapt:attr>
+ </root1>
+ </aapt:attr>
+ </base_root>)");
+
+ doc->file.name = test::ParseNameOrDie("layout/main");
+
+ InlineXmlFormatParser parser;
+ ASSERT_TRUE(parser.Consume(context.get(), doc.get()));
+ // Confirm that all of the nested inline xmls are parsed out.
+ ASSERT_THAT(parser.GetExtractedInlineXmlDocuments(), SizeIs(8u));
+}
} // namespace aapt