summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageParser.java199
-rw-r--r--core/java/android/util/EventLog.java26
-rw-r--r--core/jni/android/graphics/BitmapFactory.cpp2
-rw-r--r--core/tests/coretests/README50
-rw-r--r--core/tests/coretests/src/android/content/pm/PackageParserTest.java218
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java12
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java16
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/LayoutInflaterBuilder.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java105
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java37
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java44
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/utils/TestableContext.java57
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/utils/TestableImageView.java40
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkNotificationManager.java8
-rw-r--r--services/core/java/com/android/server/pm/Installer.java16
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java25
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java13
-rw-r--r--services/core/jni/com_android_server_ConsumerIrService.cpp2
27 files changed, 734 insertions, 240 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 32bf66a92fd5..2236291fd248 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -24,7 +24,10 @@ import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Intent;
@@ -58,7 +61,6 @@ import android.util.jar.StrictJarFile;
import android.view.Gravity;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -85,7 +87,6 @@ import java.util.zip.ZipEntry;
import libcore.io.IoUtils;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
-import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
@@ -2103,63 +2104,22 @@ public class PackageParser {
sa.recycle();
- if (minCode != null) {
- boolean allowedCodename = false;
- for (String codename : SDK_CODENAMES) {
- if (minCode.equals(codename)) {
- allowedCodename = true;
- break;
- }
- }
- if (!allowedCodename) {
- if (SDK_CODENAMES.length > 0) {
- outError[0] = "Requires development platform " + minCode
- + " (current platform is any of "
- + Arrays.toString(SDK_CODENAMES) + ")";
- } else {
- outError[0] = "Requires development platform " + minCode
- + " but this is a release platform.";
- }
- mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
- return null;
- }
- pkg.applicationInfo.minSdkVersion =
- android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
- } else if (minVers > SDK_VERSION) {
- outError[0] = "Requires newer sdk version #" + minVers
- + " (current version is #" + SDK_VERSION + ")";
+ final int minSdkVersion = PackageParser.computeMinSdkVersion(minVers, minCode,
+ SDK_VERSION, SDK_CODENAMES, outError);
+ if (minSdkVersion < 0) {
mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
return null;
- } else {
- pkg.applicationInfo.minSdkVersion = minVers;
}
- if (targetCode != null) {
- boolean allowedCodename = false;
- for (String codename : SDK_CODENAMES) {
- if (targetCode.equals(codename)) {
- allowedCodename = true;
- break;
- }
- }
- if (!allowedCodename) {
- if (SDK_CODENAMES.length > 0) {
- outError[0] = "Requires development platform " + targetCode
- + " (current platform is any of "
- + Arrays.toString(SDK_CODENAMES) + ")";
- } else {
- outError[0] = "Requires development platform " + targetCode
- + " but this is a release platform.";
- }
- mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
- return null;
- }
- // If the code matches, it definitely targets this SDK.
- pkg.applicationInfo.targetSdkVersion
- = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
- } else {
- pkg.applicationInfo.targetSdkVersion = targetVers;
+ final int targetSdkVersion = PackageParser.computeTargetSdkVersion(targetVers,
+ targetCode, SDK_VERSION, SDK_CODENAMES, outError);
+ if (targetSdkVersion < 0) {
+ mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
+ return null;
}
+
+ pkg.applicationInfo.minSdkVersion = minSdkVersion;
+ pkg.applicationInfo.targetSdkVersion = targetSdkVersion;
}
XmlUtils.skipCurrentTag(parser);
@@ -2407,6 +2367,137 @@ public class PackageParser {
return pkg;
}
+ /**
+ * Computes the targetSdkVersion to use at runtime. If the package is not
+ * compatible with this platform, populates {@code outError[0]} with an
+ * error message.
+ * <p>
+ * If {@code targetCode} is not specified, e.g. the value is {@code null},
+ * then the {@code targetVers} will be returned unmodified.
+ * <p>
+ * Otherwise, the behavior varies based on whether the current platform
+ * is a pre-release version, e.g. the {@code platformSdkCodenames} array
+ * has length > 0:
+ * <ul>
+ * <li>If this is a pre-release platform and the value specified by
+ * {@code targetCode} is contained within the array of allowed pre-release
+ * codenames, this method will return {@link Build.VERSION_CODES#CUR_DEVELOPMENT}.
+ * <li>If this is a released platform, this method will return -1 to
+ * indicate that the package is not compatible with this platform.
+ * </ul>
+ *
+ * @param targetVers targetSdkVersion number, if specified in the
+ * application manifest, or 0 otherwise
+ * @param targetCode targetSdkVersion code, if specified in the application
+ * manifest, or {@code null} otherwise
+ * @param platformSdkVersion platform SDK version number, typically
+ * Build.VERSION.SDK_INT
+ * @param platformSdkCodenames array of allowed pre-release SDK codenames
+ * for this platform
+ * @param outError output array to populate with error, if applicable
+ * @return the targetSdkVersion to use at runtime, or -1 if the package is
+ * not compatible with this platform
+ * @hide Exposed for unit testing only.
+ */
+ @TestApi
+ public static int computeTargetSdkVersion(@IntRange(from = 0) int targetVers,
+ @Nullable String targetCode, @IntRange(from = 1) int platformSdkVersion,
+ @NonNull String[] platformSdkCodenames, @NonNull String[] outError) {
+ // If it's a release SDK, return the version number unmodified.
+ if (targetCode == null) {
+ return targetVers;
+ }
+
+ // If it's a pre-release SDK and the codename matches this platform, it
+ // definitely targets this SDK.
+ if (ArrayUtils.contains(platformSdkCodenames, targetCode)) {
+ return Build.VERSION_CODES.CUR_DEVELOPMENT;
+ }
+
+ // Otherwise, we're looking at an incompatible pre-release SDK.
+ if (platformSdkCodenames.length > 0) {
+ outError[0] = "Requires development platform " + targetCode
+ + " (current platform is any of "
+ + Arrays.toString(platformSdkCodenames) + ")";
+ } else {
+ outError[0] = "Requires development platform " + targetCode
+ + " but this is a release platform.";
+ }
+ return -1;
+ }
+
+ /**
+ * Computes the minSdkVersion to use at runtime. If the package is not
+ * compatible with this platform, populates {@code outError[0]} with an
+ * error message.
+ * <p>
+ * If {@code minCode} is not specified, e.g. the value is {@code null},
+ * then behavior varies based on the {@code platformSdkVersion}:
+ * <ul>
+ * <li>If the platform SDK version is greater than or equal to the
+ * {@code minVers}, returns the {@code mniVers} unmodified.
+ * <li>Otherwise, returns -1 to indicate that the package is not
+ * compatible with this platform.
+ * </ul>
+ * <p>
+ * Otherwise, the behavior varies based on whether the current platform
+ * is a pre-release version, e.g. the {@code platformSdkCodenames} array
+ * has length > 0:
+ * <ul>
+ * <li>If this is a pre-release platform and the value specified by
+ * {@code targetCode} is contained within the array of allowed pre-release
+ * codenames, this method will return {@link Build.VERSION_CODES#CUR_DEVELOPMENT}.
+ * <li>If this is a released platform, this method will return -1 to
+ * indicate that the package is not compatible with this platform.
+ * </ul>
+ *
+ * @param minVers minSdkVersion number, if specified in the application
+ * manifest, or 1 otherwise
+ * @param minCode minSdkVersion code, if specified in the application
+ * manifest, or {@code null} otherwise
+ * @param platformSdkVersion platform SDK version number, typically
+ * Build.VERSION.SDK_INT
+ * @param platformSdkCodenames array of allowed prerelease SDK codenames
+ * for this platform
+ * @param outError output array to populate with error, if applicable
+ * @return the minSdkVersion to use at runtime, or -1 if the package is not
+ * compatible with this platform
+ * @hide Exposed for unit testing only.
+ */
+ @TestApi
+ public static int computeMinSdkVersion(@IntRange(from = 1) int minVers,
+ @Nullable String minCode, @IntRange(from = 1) int platformSdkVersion,
+ @NonNull String[] platformSdkCodenames, @NonNull String[] outError) {
+ // If it's a release SDK, make sure we meet the minimum SDK requirement.
+ if (minCode == null) {
+ if (minVers <= platformSdkVersion) {
+ return minVers;
+ }
+
+ // We don't meet the minimum SDK requirement.
+ outError[0] = "Requires newer sdk version #" + minVers
+ + " (current version is #" + platformSdkVersion + ")";
+ return -1;
+ }
+
+ // If it's a pre-release SDK and the codename matches this platform, we
+ // definitely meet the minimum SDK requirement.
+ if (ArrayUtils.contains(platformSdkCodenames, minCode)) {
+ return Build.VERSION_CODES.CUR_DEVELOPMENT;
+ }
+
+ // Otherwise, we're looking at an incompatible pre-release SDK.
+ if (platformSdkCodenames.length > 0) {
+ outError[0] = "Requires development platform " + minCode
+ + " (current platform is any of "
+ + Arrays.toString(platformSdkCodenames) + ")";
+ } else {
+ outError[0] = "Requires development platform " + minCode
+ + " but this is a release platform.";
+ }
+ return -1;
+ }
+
private FeatureInfo parseUsesFeature(Resources res, AttributeSet attrs) {
FeatureInfo fi = new FeatureInfo();
TypedArray sa = res.obtainAttributes(attrs,
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index 6196a97024e6..99f6c2a9c58d 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -56,6 +56,7 @@ public class EventLog {
/** A previously logged event read from the logs. Instances are thread safe. */
public static final class Event {
private final ByteBuffer mBuffer;
+ private Exception mLastWtf;
// Layout of event log entry received from Android logger.
// see system/core/include/log/logger.h
@@ -116,13 +117,19 @@ public class EventLog {
offset = V1_PAYLOAD_START;
}
mBuffer.limit(offset + mBuffer.getShort(LENGTH_OFFSET));
+ if ((offset + DATA_OFFSET) >= mBuffer.limit()) {
+ // no payload
+ return null;
+ }
mBuffer.position(offset + DATA_OFFSET); // Just after the tag.
return decodeObject();
} catch (IllegalArgumentException e) {
Log.wtf(TAG, "Illegal entry payload: tag=" + getTag(), e);
+ mLastWtf = e;
return null;
} catch (BufferUnderflowException e) {
Log.wtf(TAG, "Truncated entry payload: tag=" + getTag(), e);
+ mLastWtf = e;
return null;
}
}
@@ -148,6 +155,7 @@ public class EventLog {
return new String(mBuffer.array(), start, length, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.wtf(TAG, "UTF-8 is not supported", e);
+ mLastWtf = e;
return null;
}
@@ -173,6 +181,24 @@ public class EventLog {
byte[] bytes = mBuffer.array();
return Arrays.copyOf(bytes, bytes.length);
}
+
+ /**
+ * Retreive the last WTF error generated by this object.
+ * @hide
+ */
+ //VisibleForTesting
+ public Exception getLastError() {
+ return mLastWtf;
+ }
+
+ /**
+ * Clear the error state for this object.
+ * @hide
+ */
+ //VisibleForTesting
+ public void clearError() {
+ mLastWtf = null;
+ }
}
// We assume that the native methods deal with any concurrency issues.
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 69c705494932..724fccc2e91b 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -395,7 +395,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
SkAlphaType alphaType = codec->computeOutputAlphaType(requireUnpremultiplied);
const SkImageInfo decodeInfo = SkImageInfo::Make(size.width(), size.height(),
- decodeColorType, alphaType, codec->computeOutputColorSpace(decodeColorType));
+ decodeColorType, alphaType);
// We always decode to sRGB, but only mark the bitmap with a color space if linear
// blending is enabled.
diff --git a/core/tests/coretests/README b/core/tests/coretests/README
new file mode 100644
index 000000000000..4a6984320e61
--- /dev/null
+++ b/core/tests/coretests/README
@@ -0,0 +1,50 @@
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+
+
+INTRODUCTION
+
+The Android platform core tests (APCT) consist of unit tests for core platform
+functionality. These differ from CTS in that they are not necessarily testing
+public APIs and are not guaranteed to work outside of AOSP builds.
+
+
+INSTRUCTIONS
+
+To run a test or set of tests, first build the FrameworksCoreTests package:
+
+ make FrameworksCoreTests
+
+Next, install the resulting APK and run tests as you would normal JUnit tests:
+
+ adb install out/target/product/.../data/app/FrameworksCoreTests/FrameworksCoreTests.apk
+ adb shell am instrument -w \
+ com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
+
+To run a tests within a specific package, add the following argument AFTER -w:
+
+ -e package android.content.pm
+
+To run a specific test or method within a test:
+
+ -e class android.content.pm.PackageParserTest
+ -e class android.content.pm.PackageParserTest#testComputeMinSdkVersion
+
+To run tests in debug mode:
+
+ -e debug true
+
+For more arguments, see the guide to command=line testing:
+
+ https://developer.android.com/studio/test/command-line.html
diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
new file mode 100644
index 000000000000..2a3c22c64ec2
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.os.Build;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PackageParserTest {
+ private static final String RELEASED = null;
+ private static final String OLDER_PRE_RELEASE = "A";
+ private static final String PRE_RELEASE = "B";
+ private static final String NEWER_PRE_RELEASE = "C";
+
+ private static final String[] CODENAMES_RELEASED = { /* empty */ };
+ private static final String[] CODENAMES_PRE_RELEASE = { PRE_RELEASE };
+
+ private static final int OLDER_VERSION = 10;
+ private static final int PLATFORM_VERSION = 20;
+ private static final int NEWER_VERSION = 30;
+
+ private void verifyComputeMinSdkVersion(int minSdkVersion, String minSdkCodename,
+ boolean isPlatformReleased, int expectedMinSdk) {
+ final String[] outError = new String[1];
+ final int result = PackageParser.computeMinSdkVersion(
+ minSdkVersion,
+ minSdkCodename,
+ PLATFORM_VERSION,
+ isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
+ outError);
+
+ assertEquals(result, expectedMinSdk);
+
+ if (expectedMinSdk == -1) {
+ assertNotNull(outError[0]);
+ } else {
+ assertNull(outError[0]);
+ }
+ }
+
+ @Test
+ public void testComputeMinSdkVersion_preReleasePlatform() {
+ // Do allow older release minSdkVersion on pre-release platform.
+ // APP: Released API 10
+ // DEV: Pre-release API 20
+ verifyComputeMinSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION);
+
+ // Do allow same release minSdkVersion on pre-release platform.
+ // APP: Released API 20
+ // DEV: Pre-release API 20
+ verifyComputeMinSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION);
+
+ // Don't allow newer release minSdkVersion on pre-release platform.
+ // APP: Released API 30
+ // DEV: Pre-release API 20
+ verifyComputeMinSdkVersion(NEWER_VERSION, RELEASED, false, -1);
+
+ // Don't allow older pre-release minSdkVersion on pre-release platform.
+ // APP: Pre-release API 10
+ // DEV: Pre-release API 20
+ verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1);
+
+ // Do allow same pre-release minSdkVersion on pre-release platform,
+ // but overwrite the specified version with CUR_DEVELOPMENT.
+ // APP: Pre-release API 20
+ // DEV: Pre-release API 20
+ verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
+ Build.VERSION_CODES.CUR_DEVELOPMENT);
+
+ // Don't allow newer pre-release minSdkVersion on pre-release platform.
+ // APP: Pre-release API 30
+ // DEV: Pre-release API 20
+ verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1);
+ }
+
+ @Test
+ public void testComputeMinSdkVersion_releasedPlatform() {
+ // Do allow older release minSdkVersion on released platform.
+ // APP: Released API 10
+ // DEV: Released API 20
+ verifyComputeMinSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION);
+
+ // Do allow same release minSdkVersion on released platform.
+ // APP: Released API 20
+ // DEV: Released API 20
+ verifyComputeMinSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION);
+
+ // Don't allow newer release minSdkVersion on released platform.
+ // APP: Released API 30
+ // DEV: Released API 20
+ verifyComputeMinSdkVersion(NEWER_VERSION, RELEASED, true, -1);
+
+ // Don't allow older pre-release minSdkVersion on released platform.
+ // APP: Pre-release API 10
+ // DEV: Released API 20
+ verifyComputeMinSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1);
+
+ // Don't allow same pre-release minSdkVersion on released platform.
+ // APP: Pre-release API 20
+ // DEV: Released API 20
+ verifyComputeMinSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1);
+
+ // Don't allow newer pre-release minSdkVersion on released platform.
+ // APP: Pre-release API 30
+ // DEV: Released API 20
+ verifyComputeMinSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1);
+ }
+
+ private void verifyComputeTargetSdkVersion(int targetSdkVersion, String targetSdkCodename,
+ boolean isPlatformReleased, int expectedTargetSdk) {
+ final String[] outError = new String[1];
+ final int result = PackageParser.computeTargetSdkVersion(
+ targetSdkVersion,
+ targetSdkCodename,
+ PLATFORM_VERSION,
+ isPlatformReleased ? CODENAMES_RELEASED : CODENAMES_PRE_RELEASE,
+ outError);
+
+ assertEquals(result, expectedTargetSdk);
+
+ if (expectedTargetSdk == -1) {
+ assertNotNull(outError[0]);
+ } else {
+ assertNull(outError[0]);
+ }
+ }
+
+ @Test
+ public void testComputeTargetSdkVersion_preReleasePlatform() {
+ // Do allow older release targetSdkVersion on pre-release platform.
+ // APP: Released API 10
+ // DEV: Pre-release API 20
+ verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, false, OLDER_VERSION);
+
+ // Do allow same release targetSdkVersion on pre-release platform.
+ // APP: Released API 20
+ // DEV: Pre-release API 20
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, false, PLATFORM_VERSION);
+
+ // Do allow newer release targetSdkVersion on pre-release platform.
+ // APP: Released API 30
+ // DEV: Pre-release API 20
+ verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, false, NEWER_VERSION);
+
+ // Don't allow older pre-release targetSdkVersion on pre-release platform.
+ // APP: Pre-release API 10
+ // DEV: Pre-release API 20
+ verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, false, -1);
+
+ // Do allow same pre-release targetSdkVersion on pre-release platform,
+ // but overwrite the specified version with CUR_DEVELOPMENT.
+ // APP: Pre-release API 20
+ // DEV: Pre-release API 20
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, false,
+ Build.VERSION_CODES.CUR_DEVELOPMENT);
+
+ // Don't allow newer pre-release targetSdkVersion on pre-release platform.
+ // APP: Pre-release API 30
+ // DEV: Pre-release API 20
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, false, -1);
+ }
+
+ @Test
+ public void testComputeTargetSdkVersion_releasedPlatform() {
+ // Do allow older release targetSdkVersion on released platform.
+ // APP: Released API 10
+ // DEV: Released API 20
+ verifyComputeTargetSdkVersion(OLDER_VERSION, RELEASED, true, OLDER_VERSION);
+
+ // Do allow same release targetSdkVersion on released platform.
+ // APP: Released API 20
+ // DEV: Released API 20
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, RELEASED, true, PLATFORM_VERSION);
+
+ // Do allow newer release targetSdkVersion on released platform.
+ // APP: Released API 30
+ // DEV: Released API 20
+ verifyComputeTargetSdkVersion(NEWER_VERSION, RELEASED, true, NEWER_VERSION);
+
+ // Don't allow older pre-release targetSdkVersion on released platform.
+ // APP: Pre-release API 10
+ // DEV: Released API 20
+ verifyComputeTargetSdkVersion(OLDER_VERSION, OLDER_PRE_RELEASE, true, -1);
+
+ // Don't allow same pre-release targetSdkVersion on released platform.
+ // APP: Pre-release API 20
+ // DEV: Released API 20
+ verifyComputeTargetSdkVersion(PLATFORM_VERSION, PRE_RELEASE, true, -1);
+
+ // Don't allow newer pre-release targetSdkVersion on released platform.
+ // APP: Pre-release API 30
+ // DEV: Released API 20
+ verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1);
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
index f3658c38ca35..6ccba92e2e5f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryManager.java
@@ -50,19 +50,25 @@ public class CategoryManager {
private final Map<String, DashboardCategory> mCategoryByKeyMap;
private List<DashboardCategory> mCategories;
+ private String mExtraAction;
public static CategoryManager get(Context context) {
+ return get(context, null);
+ }
+
+ public static CategoryManager get(Context context, String action) {
if (sInstance == null) {
- sInstance = new CategoryManager(context);
+ sInstance = new CategoryManager(context, action);
}
return sInstance;
}
- CategoryManager(Context context) {
+ CategoryManager(Context context, String action) {
mTileByComponentCache = new ArrayMap<>();
mCategoryByKeyMap = new ArrayMap<>();
mInterestingConfigChanges = new InterestingConfigChanges();
mInterestingConfigChanges.applyNewConfig(context.getResources());
+ mExtraAction = action;
}
public synchronized DashboardCategory getTilesByCategory(Context context, String categoryKey) {
@@ -111,7 +117,7 @@ public class CategoryManager {
}
mCategoryByKeyMap.clear();
mCategories = TileUtils.getCategories(context, mTileByComponentCache,
- false /* categoryDefinedInManifest */);
+ false /* categoryDefinedInManifest */, mExtraAction);
for (DashboardCategory category : mCategories) {
mCategoryByKeyMap.put(category.key, category);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index d12e8c09b8c0..6c5a09d23c61 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -144,6 +144,19 @@ public class TileUtils {
*/
public static List<DashboardCategory> getCategories(Context context,
Map<Pair<String, String>, Tile> cache, boolean categoryDefinedInManifest) {
+ return getCategories(context, cache, categoryDefinedInManifest, null);
+ }
+
+ /**
+ * Build a list of DashboardCategory.
+ * @param categoryDefinedInManifest If true, an dummy activity must exists in manifest to
+ * represent this category (eg: .Settings$DeviceSettings)
+ * @param extraAction additional intent filter action to be used to build the dashboard
+ * categories
+ */
+ public static List<DashboardCategory> getCategories(Context context,
+ Map<Pair<String, String>, Tile> cache, boolean categoryDefinedInManifest,
+ String extraAction) {
final long startTime = System.currentTimeMillis();
boolean setup = Global.getInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0)
!= 0;
@@ -162,6 +175,9 @@ public class TileUtils {
if (setup) {
getTilesForAction(context, user, EXTRA_SETTINGS_ACTION, cache, null, tiles, false);
getTilesForAction(context, user, IA_SETTINGS_ACTION, cache, null, tiles, false);
+ if (extraAction != null) {
+ getTilesForAction(context, user, extraAction, cache, null, tiles, false);
+ }
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index 86b210ac4aef..c6c6aad22cf0 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -26,6 +26,8 @@ import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings.Global;
import android.util.ArrayMap;
import android.util.Pair;
@@ -34,6 +36,7 @@ import com.android.settingslib.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@@ -46,6 +49,7 @@ import java.util.Map;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
@@ -59,6 +63,8 @@ public class TileUtilsTest {
private PackageManager mPackageManager;
@Mock
private Resources mResources;
+ @Mock
+ private UserManager mUserManager;
@Before
public void setUp() throws NameNotFoundException {
@@ -127,6 +133,30 @@ public class TileUtilsTest {
assertThat(outTiles.isEmpty()).isTrue();
}
+ @Test
+ public void getCategories_shouldHandleExtraIntentAction() {
+ final String testCategory = "category1";
+ final String testAction = "action1";
+ Map<Pair<String, String>, Tile> cache = new ArrayMap<>();
+ List<ResolveInfo> info = new ArrayList<>();
+ info.add(newInfo(true, testCategory));
+ Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
+ when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+ List<UserHandle> userHandleList = new ArrayList<>();
+ userHandleList.add(UserHandle.CURRENT);
+ when(mUserManager.getUserProfiles()).thenReturn(userHandleList);
+
+ when(mPackageManager.queryIntentActivitiesAsUser(argThat(new ArgumentMatcher<Intent>() {
+ public boolean matches(Object event) {
+ return testAction.equals(((Intent) event).getAction());
+ }
+ }), anyInt(), anyInt())).thenReturn(info);
+
+ List<DashboardCategory> categoryList = TileUtils.getCategories(
+ mContext, cache, false /* categoryDefinedInManifest */, testAction);
+
+ assertThat(categoryList.get(0).tiles.get(0).category).isEqualTo(testCategory);
+ }
private ResolveInfo newInfo(boolean systemApp, String category) {
return newInfo(systemApp, category, null);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 9bbead46c33b..0be53b4b7c26 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -60,8 +60,6 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
private final QSDetailClipper mClipper;
- private PhoneStatusBar mPhoneStatusBar;
-
private boolean isShown;
private QSTileHost mHost;
private RecyclerView mRecyclerView;
@@ -119,7 +117,6 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
public void setHost(QSTileHost host) {
mHost = host;
- mPhoneStatusBar = host.getPhoneStatusBar();
mTileAdapter.setHost(host);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 6f00f521407c..137138127775 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -721,7 +721,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
if (task.isFreeformTask()) {
mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task,
stackScroller.getStackScroll(), mTmpTransform, null,
- windowOverrideRect);
+ windowOverrideRect, false /* useGridLayout */);
Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform,
mThumbTransitionBitmapCache);
Rect toTaskRect = new Rect();
@@ -771,7 +771,8 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
stackView.updateLayoutAlgorithm(true /* boundScroll */);
stackView.updateToInitialState();
stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
- stackView.getScroller().getStackScroll(), mTmpTransform, null, windowOverrideRect);
+ stackView.getScroller().getStackScroll(), mTmpTransform, null, windowOverrideRect,
+ Recents.getConfiguration().isGridEnabled);
return mTmpTransform;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 3d528bed9fa9..052985647453 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -886,10 +886,10 @@ public class TaskStackLayoutAlgorithm {
*/
public TaskViewTransform getStackTransformScreenCoordinates(Task task, float stackScroll,
TaskViewTransform transformOut, TaskViewTransform frontTransform,
- Rect windowOverrideRect) {
+ Rect windowOverrideRect, boolean useGridLayout) {
TaskViewTransform transform = getStackTransform(task, stackScroll, mFocusState,
transformOut, frontTransform, true /* forceUpdate */,
- false /* ignoreTaskOverrides */, false /* useGridLayout */);
+ false /* ignoreTaskOverrides */, useGridLayout);
return transformToScreenCoordinates(transform, windowOverrideRect);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 71f559be6775..33fa3b0eb10a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -168,7 +168,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
/** Touch preprocessing for handling below */
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Pass through to swipe helper if we are swiping
- mInterceptedBySwipeHelper = mSwipeHelper.onInterceptTouchEvent(ev);
+ mInterceptedBySwipeHelper = isSwipingEnabled() && mSwipeHelper.onInterceptTouchEvent(ev);
if (mInterceptedBySwipeHelper) {
return true;
}
@@ -680,4 +680,11 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
public float getScaledDismissSize() {
return 1.5f * Math.max(mSv.getWidth(), mSv.getHeight());
}
+
+ /**
+ * Returns whether swiping is enabled.
+ */
+ private boolean isSwipingEnabled() {
+ return !mSv.useGridLayout();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java
index 325e71a847b0..630040098d10 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java
@@ -42,7 +42,7 @@ public class GridTaskView extends TaskView {
public GridTaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mHeaderHeight = context.getResources().getDimensionPixelSize(
- R.dimen.recents_task_view_header_height);
+ R.dimen.recents_grid_task_view_header_height);
}
@Override
@@ -65,7 +65,7 @@ public class GridTaskView extends TaskView {
protected void onConfigurationChanged() {
super.onConfigurationChanged();
mHeaderHeight = mContext.getResources().getDimensionPixelSize(
- R.dimen.recents_task_view_header_height);
+ R.dimen.recents_grid_task_view_header_height);
mThumbnailView.setTranslationY(mHeaderHeight);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 567ab3b5966d..227ebdfacbda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -165,10 +165,6 @@ public class QSTileHost implements QSTile.Host, Tunable {
mHeader = view;
}
- public PhoneStatusBar getPhoneStatusBar() {
- return mStatusBar;
- }
-
public void destroy() {
mHandlerThread.quitSafely();
mTiles.values().forEach(tile -> tile.destroy());
diff --git a/packages/SystemUI/src/com/android/systemui/util/LayoutInflaterBuilder.java b/packages/SystemUI/src/com/android/systemui/util/LayoutInflaterBuilder.java
index f42092130af1..5cfe677efd57 100644
--- a/packages/SystemUI/src/com/android/systemui/util/LayoutInflaterBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/util/LayoutInflaterBuilder.java
@@ -81,11 +81,23 @@ public class LayoutInflaterBuilder {
* @return Builder object post-modification.
*/
public LayoutInflaterBuilder replace(@NonNull Class from, @NonNull Class to) {
+ return replace(from.getName(), to);
+ }
+
+ /**
+ * Instructs the Builder to configure the LayoutInflater such that all instances
+ * of one {@link View} will be replaced with instances of another during inflation.
+ *
+ * @param tag Instances of this tag will be replaced during inflation.
+ * @param to Instances of this class will be inflated as replacements.
+ * @return Builder object post-modification.
+ */
+ public LayoutInflaterBuilder replace(@NonNull String tag, @NonNull Class to) {
assertIfAlreadyBuilt();
if (mReplaceMap == null) {
mReplaceMap = new ArrayMap<String, String>();
}
- mReplaceMap.put(from.getName(), to.getName());
+ mReplaceMap.put(tag, to.getName());
return this;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
index 391c45fb8487..8acd6ba5e1d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterTest.java
@@ -14,37 +14,31 @@
package com.android.systemui.qs;
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
-import android.content.res.Resources;
+import android.os.Handler;
import android.os.Looper;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.SpannableStringBuilder;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageView;
import android.widget.TextView;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.policy.SecurityController;
+import com.android.systemui.util.LayoutInflaterBuilder;
+import com.android.systemui.utils.TestableImageView;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static junit.framework.Assert.assertEquals;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
public class QSFooterTest extends SysuiTestCase {
@@ -53,28 +47,26 @@ public class QSFooterTest extends SysuiTestCase {
private final String DEVICE_OWNER_PACKAGE = "TestDPC";
private final String VPN_PACKAGE = "TestVPN";
- private ViewGroup mRootView = mock(ViewGroup.class);
- private TextView mFooterText = mock(TextView.class);
- private ImageView mFooterIcon = mock(ImageView.class);
- private ImageView mFooterIcon2 = mock(ImageView.class);
+ private ViewGroup mRootView;
+ private TextView mFooterText;
+ private TestableImageView mFooterIcon;
+ private TestableImageView mFooterIcon2;
private QSFooter mFooter;
- private Resources mResources;
private SecurityController mSecurityController = mock(SecurityController.class);
@Before
public void setUp() {
- when(mRootView.findViewById(R.id.footer_text)).thenReturn(mFooterText);
- when(mRootView.findViewById(R.id.footer_icon)).thenReturn(mFooterIcon);
- when(mRootView.findViewById(R.id.footer_icon2)).thenReturn(mFooterIcon2);
- final LayoutInflater layoutInflater = mock(LayoutInflater.class);
- when(layoutInflater.inflate(eq(R.layout.quick_settings_footer), anyObject(), anyBoolean()))
- .thenReturn(mRootView);
- final Context context = mock(Context.class);
- when(context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).thenReturn(layoutInflater);
- mResources = mContext.getResources();
- when(context.getResources()).thenReturn(mResources);
- mFooter = new QSFooter(null, context);
- reset(mRootView);
+ mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
+ new LayoutInflaterBuilder(mContext)
+ .replace("ImageView", TestableImageView.class)
+ .build());
+ Handler h = new Handler(Looper.getMainLooper());
+ h.post(() -> mFooter = new QSFooter(null, mContext));
+ waitForIdleSync(h);
+ mRootView = (ViewGroup) mFooter.getView();
+ mFooterText = (TextView) mRootView.findViewById(R.id.footer_text);
+ mFooterIcon = (TestableImageView) mRootView.findViewById(R.id.footer_icon);
+ mFooterIcon2 = (TestableImageView) mRootView.findViewById(R.id.footer_icon2);
mFooter.setHostEnvironment(null, mSecurityController, Looper.getMainLooper());
}
@@ -86,8 +78,7 @@ public class QSFooterTest extends SysuiTestCase {
mFooter.refreshState();
waitForIdleSync(mFooter.mHandler);
- verify(mRootView).setVisibility(View.GONE);
- verifyNoMoreInteractions(mRootView);
+ assertEquals(View.GONE, mRootView.getVisibility());
}
@Test
@@ -97,10 +88,8 @@ public class QSFooterTest extends SysuiTestCase {
mFooter.refreshState();
waitForIdleSync(mFooter.mHandler);
- verify(mFooterText).setText(mResources.getString(R.string.do_disclosure_generic));
- verifyNoMoreInteractions(mFooterText);
- verify(mRootView).setVisibility(View.VISIBLE);
- verifyNoMoreInteractions(mRootView);
+ assertEquals(mContext.getString(R.string.do_disclosure_generic), mFooterText.getText());
+ assertEquals(View.VISIBLE, mRootView.getVisibility());
}
@Test
@@ -111,11 +100,9 @@ public class QSFooterTest extends SysuiTestCase {
mFooter.refreshState();
waitForIdleSync(mFooter.mHandler);
- verify(mFooterText).setText(mResources.getString(R.string.do_disclosure_with_name,
- MANAGING_ORGANIZATION));
- verifyNoMoreInteractions(mFooterText);
- verify(mRootView).setVisibility(View.VISIBLE);
- verifyNoMoreInteractions(mRootView);
+ assertEquals(mContext.getString(R.string.do_disclosure_with_name, MANAGING_ORGANIZATION),
+ mFooterText.getText());
+ assertEquals(View.VISIBLE, mRootView.getVisibility());
}
@Test
@@ -126,9 +113,9 @@ public class QSFooterTest extends SysuiTestCase {
mFooter.refreshState();
waitForIdleSync(mFooter.mHandler);
- verify(mFooterIcon).setVisibility(View.VISIBLE);
- verify(mFooterIcon).setImageResource(R.drawable.ic_qs_network_logging);
- verify(mFooterIcon2).setVisibility(View.INVISIBLE);
+ assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
+ assertEquals(R.drawable.ic_qs_network_logging, mFooterIcon.getLastImageResource());
+ assertEquals(View.INVISIBLE, mFooterIcon2.getVisibility());
}
@Test
@@ -140,9 +127,10 @@ public class QSFooterTest extends SysuiTestCase {
mFooter.refreshState();
waitForIdleSync(mFooter.mHandler);
- verify(mFooterIcon).setVisibility(View.VISIBLE);
- verify(mFooterIcon, never()).setImageResource(anyInt());
- verify(mFooterIcon2).setVisibility(View.INVISIBLE);
+ assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
+ // -1 == never set.
+ assertEquals(-1, mFooterIcon.getLastImageResource());
+ assertEquals(View.INVISIBLE, mFooterIcon2.getVisibility());
}
@Test
@@ -154,10 +142,11 @@ public class QSFooterTest extends SysuiTestCase {
mFooter.refreshState();
waitForIdleSync(mFooter.mHandler);
- verify(mFooterIcon).setVisibility(View.VISIBLE);
- verify(mFooterIcon, never()).setImageResource(anyInt());
- verify(mFooterIcon2).setVisibility(View.VISIBLE);
- verify(mFooterIcon2, never()).setImageResource(anyInt());
+ assertEquals(View.VISIBLE, mFooterIcon.getVisibility());
+ assertEquals(View.VISIBLE, mFooterIcon2.getVisibility());
+ // -1 == never set.
+ assertEquals(-1, mFooterIcon.getLastImageResource());
+ assertEquals(-1, mFooterIcon2.getLastImageResource());
}
@Test
@@ -211,15 +200,15 @@ public class QSFooterTest extends SysuiTestCase {
private CharSequence getExpectedMessage(boolean hasDeviceOwnerOrganization, boolean hasVPN) {
final SpannableStringBuilder message = new SpannableStringBuilder();
message.append(hasDeviceOwnerOrganization ?
- mResources.getString(R.string.monitoring_description_do_header_with_name,
+ mContext.getString(R.string.monitoring_description_do_header_with_name,
MANAGING_ORGANIZATION, DEVICE_OWNER_PACKAGE) :
- mResources.getString(R.string.monitoring_description_do_header_generic,
+ mContext.getString(R.string.monitoring_description_do_header_generic,
DEVICE_OWNER_PACKAGE));
message.append("\n\n");
- message.append(mResources.getString(R.string.monitoring_description_do_body));
- message.append(mResources.getString(
+ message.append(mContext.getString(R.string.monitoring_description_do_body));
+ message.append(mContext.getString(
R.string.monitoring_description_do_learn_more_separator));
- message.append(mResources.getString(R.string.monitoring_description_do_learn_more),
+ message.append(mContext.getString(R.string.monitoring_description_do_learn_more),
mFooter.new EnterprisePrivacySpan(), 0);
return message;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 350a95ff66f4..c0d5bbd35690 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -63,7 +63,7 @@ public class QSFragmentTest extends FragmentTestCase {
when(userSwitcher.getKeyguardMonitor()).thenReturn(keyguardMonitor);
when(userSwitcher.getUsers()).thenReturn(new ArrayList<>());
QSTileHost host = new QSTileHost(mContext,
- mock(PhoneStatusBar.class),
+ null,
getLeakChecker(BluetoothController.class),
getLeakChecker(LocationController.class),
getLeakChecker(RotationLockController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
index 782a4890ba55..66ec7dd3f270 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
@@ -15,8 +15,10 @@
*/
package com.android.systemui.qs.external;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
@@ -26,9 +28,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
-import android.content.ServiceConnection;
import android.content.pm.PackageInfo;
import android.content.pm.ServiceInfo;
import android.net.Uri;
@@ -50,15 +50,12 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class TileLifecycleManagerTest extends SysuiTestCase {
private static final int TEST_FAIL_TIMEOUT = 5000;
- private final Context mMockContext = Mockito.mock(Context.class);
private final PackageManagerAdapter mMockPackageManagerAdapter =
Mockito.mock(PackageManagerAdapter.class);
private final IQSTileService.Stub mMockTileService = Mockito.mock(IQSTileService.Stub.class);
@@ -77,19 +74,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
// Stub.asInterface will just return itself.
when(mMockTileService.queryLocalInterface(anyString())).thenReturn(mMockTileService);
- // Default behavior for bind is success and connects as mMockTileService.
- when(mMockContext.bindServiceAsUser(any(), any(), anyInt(), any()))
- .thenAnswer(
- new Answer<Boolean>() {
- @Override
- public Boolean answer(InvocationOnMock invocation) {
- ServiceConnection connection =
- (ServiceConnection) invocation.getArguments()[1];
- connection.onServiceConnected(
- mTileServiceComponentName, mMockTileService);
- return true;
- }
- });
+ mContext.addMockService(mTileServiceComponentName, mMockTileService);
mTileServiceIntent = new Intent().setComponent(mTileServiceComponentName);
@@ -97,7 +82,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
mThread = new HandlerThread("TestThread");
mThread.start();
mHandler = new Handler(mThread.getLooper());
- mStateManager = new TileLifecycleManager(mHandler, mMockContext,
+ mStateManager = new TileLifecycleManager(mHandler, mContext,
Mockito.mock(IQSService.class), new Tile(),
mTileServiceIntent,
mUser,
@@ -126,11 +111,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
}
private void verifyBind(int times) {
- verify(mMockContext, times(times)).bindServiceAsUser(
- mTileServiceIntent,
- mStateManager,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE,
- mUser);
+ assertEquals(times > 0, mContext.isBound(mTileServiceComponentName));
}
@Test
@@ -143,7 +124,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
public void testUnbind() {
mStateManager.setBindService(true);
mStateManager.setBindService(false);
- verify(mMockContext).unbindService(mStateManager);
+ assertFalse(mContext.isBound(mTileServiceComponentName));
}
@Test
@@ -203,7 +184,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
verifyBind(1);
mStateManager.setBindService(false);
- verify(mMockContext).unbindService(mStateManager);
+ assertFalse(mContext.isBound(mTileServiceComponentName));
verify(mMockTileService, never()).onStartListening();
}
@@ -217,7 +198,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
verifyBind(1);
mStateManager.setBindService(false);
- verify(mMockContext).unbindService(mStateManager);
+ assertFalse(mContext.isBound(mTileServiceComponentName));
verify(mMockTileService, never()).onClick(null);
}
@@ -233,7 +214,7 @@ public class TileLifecycleManagerTest extends SysuiTestCase {
// Package is re-enabled.
setPackageEnabled(true);
mStateManager.onReceive(
- mMockContext,
+ mContext,
new Intent(
Intent.ACTION_PACKAGE_CHANGED,
Uri.fromParts(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 639c8daf586b..7335af3fff9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -16,15 +16,18 @@
package com.android.systemui.statusbar;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
-import android.content.ContentResolver;
import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.Looper;
import android.support.test.runner.AndroidJUnit4;
-import android.telephony.SubscriptionManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;
import android.view.ViewGroup;
@@ -37,22 +40,15 @@ import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class KeyguardIndicationControllerTest extends SysuiTestCase {
private final String ORGANIZATION_NAME = "organization";
- private final String DISCLOSURE_WITH_ORGANIZATION_NAME = "managed by organization";
- private Context mContext = mock(Context.class);
+ private String mDisclosureWithOrganization;
+
private DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
private ViewGroup mIndicationArea = mock(ViewGroup.class);
private KeyguardIndicationTextView mDisclosure = mock(KeyguardIndicationTextView.class);
@@ -61,19 +57,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- final Resources resources = mock(Resources.class);
- when(mContext.getResources()).thenReturn(resources);
- when(mContext.getContentResolver()).thenReturn(mock(ContentResolver.class));
- when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
- when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)).thenReturn(
- mock(SubscriptionManager.class));
- when(mContext.getSystemService(Context.TRUST_SERVICE)).thenReturn(
- mock(TrustManager.class));
- when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
- mDevicePolicyManager);
-
- when(resources.getString(R.string.do_disclosure_with_name, ORGANIZATION_NAME))
- .thenReturn(DISCLOSURE_WITH_ORGANIZATION_NAME);
+ mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
+ mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
+ mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
+ mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
+ ORGANIZATION_NAME);
when(mIndicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure))
.thenReturn(mDisclosure);
@@ -113,7 +101,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
createController();
verify(mDisclosure).setVisibility(View.VISIBLE);
- verify(mDisclosure).switchIndication(DISCLOSURE_WITH_ORGANIZATION_NAME);
+ verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
verifyNoMoreInteractions(mDisclosure);
}
@@ -140,7 +128,7 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
monitor.onKeyguardVisibilityChanged(true);
verify(mDisclosure).setVisibility(View.VISIBLE);
- verify(mDisclosure).switchIndication(DISCLOSURE_WITH_ORGANIZATION_NAME);
+ verify(mDisclosure).switchIndication(mDisclosureWithOrganization);
verifyNoMoreInteractions(mDisclosure);
reset(mDisclosure);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
index 9a697eedc2e1..87c4c664f352 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SecurityControllerTest.java
@@ -16,26 +16,24 @@
package com.android.systemui.statusbar.policy;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.app.admin.DevicePolicyManager;
import android.content.Context;
-import android.content.pm.UserInfo;
import android.net.ConnectivityManager;
-import android.os.UserManager;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.systemui.SysuiTestCase;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -45,16 +43,9 @@ public class SecurityControllerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- final Context context = mock(Context.class);
- when(context.getSystemService(Context.DEVICE_POLICY_SERVICE))
- .thenReturn(mDevicePolicyManager);
- when(context.getSystemService(Context.CONNECTIVITY_SERVICE))
- .thenReturn(mock(ConnectivityManager.class));
- final UserManager userManager = mock(UserManager.class);
- when(userManager.getUserInfo(anyInt())).thenReturn(mock(UserInfo.class));
- when(context.getSystemService(Context.USER_SERVICE))
- .thenReturn(userManager);
- mSecurityController = new SecurityControllerImpl(context);
+ mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
+ mContext.addMockSystemService(Context.CONNECTIVITY_SERVICE, mock(ConnectivityManager.class));
+ mSecurityController = new SecurityControllerImpl(mContext);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/TestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/utils/TestableContext.java
index bf73416ffcff..a95280641aa1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/TestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/TestableContext.java
@@ -16,15 +16,19 @@ package com.android.systemui.utils;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks;
+import android.content.ComponentName;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.res.Resources;
import android.os.Handler;
+import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.ArrayMap;
import com.android.systemui.utils.leaks.Tracker;
import com.android.systemui.SysuiTestCase;
@@ -34,6 +38,10 @@ public class TestableContext extends ContextWrapper {
private final FakeContentResolver mFakeContentResolver;
private final FakeSettingsProvider mSettingsProvider;
+ private ArrayMap<String, Object> mMockSystemServices;
+ private ArrayMap<ComponentName, IBinder> mMockServices;
+ private ArrayMap<ServiceConnection, ComponentName> mActiveServices;
+
private Tracker mReceiver;
private Tracker mService;
private Tracker mComponent;
@@ -51,6 +59,33 @@ public class TestableContext extends ContextWrapper {
mComponent = test.getTracker("component");
}
+ @Override
+ public Resources getResources() {
+ return super.getResources();
+ }
+
+ public void addMockSystemService(String name, Object service) {
+ mMockSystemServices = lazyInit(mMockSystemServices);
+ mMockSystemServices.put(name, service);
+ }
+
+ public void addMockService(ComponentName component, IBinder service) {
+ mMockServices = lazyInit(mMockServices);
+ mMockServices.put(component, service);
+ }
+
+ private <T, V> ArrayMap<T, V> lazyInit(ArrayMap<T, V> services) {
+ return services != null ? services : new ArrayMap<T, V>();
+ }
+
+ @Override
+ public Object getSystemService(String name) {
+ if (mMockSystemServices != null && mMockSystemServices.containsKey(name)) {
+ return mMockSystemServices.get(name);
+ }
+ return super.getSystemService(name);
+ }
+
public FakeSettingsProvider getSettingsProvider() {
return mSettingsProvider;
}
@@ -96,6 +131,7 @@ public class TestableContext extends ContextWrapper {
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
if (mService != null) mService.getLeakInfo(conn).addAllocation(new Throwable());
+ if (checkMocks(service.getComponent(), conn)) return true;
return super.bindService(service, conn, flags);
}
@@ -103,6 +139,7 @@ public class TestableContext extends ContextWrapper {
public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
Handler handler, UserHandle user) {
if (mService != null) mService.getLeakInfo(conn).addAllocation(new Throwable());
+ if (checkMocks(service.getComponent(), conn)) return true;
return super.bindServiceAsUser(service, conn, flags, handler, user);
}
@@ -110,15 +147,35 @@ public class TestableContext extends ContextWrapper {
public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
UserHandle user) {
if (mService != null) mService.getLeakInfo(conn).addAllocation(new Throwable());
+ if (checkMocks(service.getComponent(), conn)) return true;
return super.bindServiceAsUser(service, conn, flags, user);
}
+ private boolean checkMocks(ComponentName component, ServiceConnection conn) {
+ if (mMockServices != null && component != null && mMockServices.containsKey(component)) {
+ mActiveServices = lazyInit(mActiveServices);
+ mActiveServices.put(conn, component);
+ conn.onServiceConnected(component, mMockServices.get(component));
+ return true;
+ }
+ return false;
+ }
+
@Override
public void unbindService(ServiceConnection conn) {
if (mService != null) mService.getLeakInfo(conn).clearAllocations();
+ if (mActiveServices != null && mActiveServices.containsKey(conn)) {
+ conn.onServiceDisconnected(mActiveServices.get(conn));
+ mActiveServices.remove(conn);
+ return;
+ }
super.unbindService(conn);
}
+ public boolean isBound(ComponentName component) {
+ return mActiveServices != null && mActiveServices.containsValue(component);
+ }
+
@Override
public void registerComponentCallbacks(ComponentCallbacks callback) {
if (mComponent != null) mComponent.getLeakInfo(callback).addAllocation(new Throwable());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/TestableImageView.java b/packages/SystemUI/tests/src/com/android/systemui/utils/TestableImageView.java
new file mode 100644
index 000000000000..b131460e1eff
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/TestableImageView.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.utils;
+
+import android.annotation.DrawableRes;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+public class TestableImageView extends ImageView {
+
+ private int mLastResId = -1;
+
+ public TestableImageView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void setImageResource(@DrawableRes int resId) {
+ mLastResId = resId;
+ super.setImageResource(resId);
+ }
+
+ public int getLastImageResource() {
+ return mLastResId;
+ }
+}
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 2fbdbeb7c660..c0550c6c7876 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -143,7 +143,8 @@ public class NetworkNotificationManager {
if (DBG) {
Slog.d(TAG, String.format(
"showNotification tag=%s event=%s transport=%s extraInfo=%s highPrioriy=%s",
- tag, nameOf(eventId), getTransportName(transportType), extraInfo, highPriority));
+ tag, nameOf(eventId), getTransportName(transportType), extraInfo,
+ highPriority));
}
Resources r = Resources.getSystem();
@@ -227,13 +228,14 @@ public class NetworkNotificationManager {
}
final int eventId = mNotificationTypeMap.get(id);
if (DBG) {
- Slog.d(TAG, String.format("clearing notification tag=%s event=", tag, nameOf(eventId)));
+ Slog.d(TAG, String.format("clearing notification tag=%s event=%s", tag,
+ nameOf(eventId)));
}
try {
mNotificationManager.cancelAsUser(tag, eventId, UserHandle.ALL);
} catch (NullPointerException npe) {
Slog.d(TAG, String.format(
- "failed to clear notification tag=%s event=", tag, nameOf(eventId)), npe);
+ "failed to clear notification tag=%s event=%s", tag, nameOf(eventId)), npe);
}
mNotificationTypeMap.delete(id);
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 31939749ee66..203f841bb305 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -105,11 +105,11 @@ public class Installer extends SystemService {
}
}
- public void createAppData(String uuid, String packageName, int userId, int flags, int appId,
+ public long createAppData(String uuid, String packageName, int userId, int flags, int appId,
String seInfo, int targetSdkVersion) throws InstallerException {
- if (!checkBeforeRemote()) return;
+ if (!checkBeforeRemote()) return -1;
try {
- mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo,
+ return mInstalld.createAppData(uuid, packageName, userId, flags, appId, seInfo,
targetSdkVersion);
} catch (Exception e) {
throw InstallerException.from(e);
@@ -182,16 +182,6 @@ public class Installer extends SystemService {
}
}
- public long getAppDataInode(String uuid, String packageName, int userId, int flags)
- throws InstallerException {
- if (!checkBeforeRemote()) return -1;
- try {
- return mInstalld.getAppDataInode(uuid, packageName, userId, flags);
- } catch (Exception e) {
- throw InstallerException.from(e);
- }
- }
-
public void dexopt(String apkPath, int uid, @Nullable String pkgName, String instructionSet,
int dexoptNeeded, @Nullable String outputPath, int dexFlags,
String compilerFilter, @Nullable String volumeUuid, @Nullable String sharedLibraries)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index df1de11a008b..4937662b91d4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -20459,8 +20459,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
Preconditions.checkNotNull(app.seinfo);
+ long ceDataInode = -1;
try {
- mInstaller.createAppData(volumeUuid, packageName, userId, flags,
+ ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
appId, app.seinfo, app.targetSdkVersion);
} catch (InstallerException e) {
if (app.isSystemApp()) {
@@ -20468,7 +20469,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
+ ", but trying to recover: " + e);
destroyAppDataLeafLIF(pkg, userId, flags);
try {
- mInstaller.createAppData(volumeUuid, packageName, userId, flags,
+ ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
appId, app.seinfo, app.targetSdkVersion);
logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
} catch (InstallerException e2) {
@@ -20479,21 +20480,13 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
}
- if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
- try {
- // CE storage is unlocked right now, so read out the inode and
- // remember for use later when it's locked
- // TODO: mark this structure as dirty so we persist it!
- final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId,
- StorageManager.FLAG_STORAGE_CE);
- synchronized (mPackages) {
- final PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps != null) {
- ps.setCeDataInode(ceDataInode, userId);
- }
+ if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
+ // TODO: mark this structure as dirty so we persist it!
+ synchronized (mPackages) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps != null) {
+ ps.setCeDataInode(ceDataInode, userId);
}
- } catch (InstallerException e) {
- Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e);
}
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 3645c24043ca..8f64353a362d 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1556,6 +1556,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
}
final long ident = Binder.clearCallingIdentity();
+
+ // Live wallpapers can't be specified for keyguard. If we're using a static
+ // system+lock image currently, migrate the system wallpaper to be a lock-only
+ // image as part of making a different live component active as the system
+ // wallpaper.
+ if (mImageWallpaper.equals(wallpaper.wallpaperComponent)) {
+ if (mLockWallpaperMap.get(userId) == null) {
+ // We're using the static imagery and there is no lock-specific image in place,
+ // therefore it's a shared system+lock image that we need to migrate.
+ migrateSystemToLockWallpaperLocked(userId);
+ }
+ }
+
try {
wallpaper.imageWallpaperPending = false;
if (bindWallpaperComponentLocked(name, false, true, wallpaper, null)) {
diff --git a/services/core/jni/com_android_server_ConsumerIrService.cpp b/services/core/jni/com_android_server_ConsumerIrService.cpp
index 5906e6b602ef..1f7bf4a05ad4 100644
--- a/services/core/jni/com_android_server_ConsumerIrService.cpp
+++ b/services/core/jni/com_android_server_ConsumerIrService.cpp
@@ -49,7 +49,7 @@ static jint halTransmit(JNIEnv *env, jobject /* obj */, jint carrierFrequency,
hidl_vec<int32_t> patternVec;
patternVec.setToExternal(const_cast<int32_t*>(cPattern.get()), cPattern.size());
- bool success = mHal->transmit(carrierFrequency, patternVec, cPattern.size());
+ bool success = mHal->transmit(carrierFrequency, patternVec);
return success ? 0 : -1;
}