summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/DisplayCutout.java27
-rw-r--r--core/tests/coretests/src/android/view/DisplayCutoutTest.java4
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java79
3 files changed, 61 insertions, 49 deletions
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 715181f28076..797c128e514c 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -319,18 +319,23 @@ public final class DisplayCutout {
sortedBounds[i] = ZERO_RECT;
}
if (safeInsets != null && boundingRects != null) {
+ // There is at most one non-functional area per short edge of the device, but none
+ // on the long edges, so either a) safeInsets.top and safeInsets.bottom is 0, or
+ // b) safeInsets.left and safeInset.right is 0.
+ final boolean topBottomInset = safeInsets.top > 0 || safeInsets.bottom > 0;
for (Rect bound : boundingRects) {
- // There is at most one non-functional area per short edge of the device, but none
- // on the long edges, so either safeInsets.right or safeInsets.bottom must be 0.
- // TODO(b/117199965): Refine the logic to handle edge cases.
- if (bound.left == 0) {
- sortedBounds[BOUNDS_POSITION_LEFT] = bound;
- } else if (bound.top == 0) {
- sortedBounds[BOUNDS_POSITION_TOP] = bound;
- } else if (safeInsets.right > 0) {
- sortedBounds[BOUNDS_POSITION_RIGHT] = bound;
- } else if (safeInsets.bottom > 0) {
- sortedBounds[BOUNDS_POSITION_BOTTOM] = bound;
+ if (topBottomInset) {
+ if (bound.top == 0) {
+ sortedBounds[BOUNDS_POSITION_TOP] = bound;
+ } else {
+ sortedBounds[BOUNDS_POSITION_BOTTOM] = bound;
+ }
+ } else {
+ if (bound.left == 0) {
+ sortedBounds[BOUNDS_POSITION_LEFT] = bound;
+ } else {
+ sortedBounds[BOUNDS_POSITION_RIGHT] = bound;
+ }
}
}
}
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index 182fe78dfa7a..d5a0dfadcbe5 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -104,8 +104,8 @@ public class DisplayCutoutTest {
@Test
public void testExtractBoundsFromList_top_and_bottom() {
- Rect safeInsets = new Rect(0, 1, 0, 10);
- Rect boundTop = new Rect(80, 0, 120, 10);
+ Rect safeInsets = new Rect(0, 10, 0, 10);
+ Rect boundTop = new Rect(0, 0, 120, 10);
Rect boundBottom = new Rect(80, 190, 120, 200);
assertThat(extractBoundsFromList(safeInsets,
Arrays.asList(new Rect[]{boundTop, boundBottom})),
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 42b65c357959..bf141a0f139b 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -242,11 +242,11 @@ public class StagingManager {
}
if (sessionContainsApk(session)) {
- if (!installApksInSession(session, /* preReboot */ true)) {
- session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_VERIFICATION_FAILED,
- "APK verification failed. Check logcat messages for "
- + "more information.");
+ try {
+ installApksInSession(session, /* preReboot */ true);
// TODO(b/118865310): abort the session on apexd.
+ } catch (PackageManagerException e) {
+ session.setStagedSessionFailed(e.error, e.getMessage());
return;
}
}
@@ -315,7 +315,7 @@ public class StagingManager {
}
private void resumeSession(@NonNull PackageInstallerSession session) {
- boolean hasApex = sessionContainsApex(session);
+ final boolean hasApex = sessionContainsApex(session);
if (hasApex) {
// Check with apexservice whether the apex packages have been activated.
ApexSessionInfo apexSessionInfo = mApexManager.getStagedSessionInfo(session.sessionId);
@@ -350,10 +350,10 @@ public class StagingManager {
}
}
// The APEX part of the session is activated, proceed with the installation of APKs.
- if (!installApksInSession(session, /* preReboot */ false)) {
- session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
- "Staged installation of APKs failed. Check logcat messages for"
- + "more information.");
+ try {
+ installApksInSession(session, /* preReboot */ false);
+ } catch (PackageManagerException e) {
+ session.setStagedSessionFailed(e.error, e.getMessage());
if (!hasApex) {
return;
@@ -388,16 +388,22 @@ public class StagingManager {
return ret;
}
+ @NonNull
private PackageInstallerSession createAndWriteApkSession(
- @NonNull PackageInstallerSession originalSession, boolean preReboot) {
+ @NonNull PackageInstallerSession originalSession, boolean preReboot)
+ throws PackageManagerException {
+ final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
+ : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
if (originalSession.stageDir == null) {
Slog.wtf(TAG, "Attempting to install a staged APK session with no staging dir");
- return null;
+ throw new PackageManagerException(errorCode,
+ "Attempting to install a staged APK session with no staging dir");
}
List<String> apkFilePaths = findAPKsInDir(originalSession.stageDir);
if (apkFilePaths.isEmpty()) {
Slog.w(TAG, "Can't find staged APK in " + originalSession.stageDir.getAbsolutePath());
- return null;
+ throw new PackageManagerException(errorCode,
+ "Can't find staged APK in " + originalSession.stageDir.getAbsolutePath());
}
PackageInstaller.SessionParams params = originalSession.params.copy();
@@ -424,20 +430,22 @@ public class StagingManager {
long sizeBytes = pfd.getStatSize();
if (sizeBytes < 0) {
Slog.e(TAG, "Unable to get size of: " + apkFilePath);
- return null;
+ throw new PackageManagerException(errorCode,
+ "Unable to get size of: " + apkFilePath);
}
apkSession.write(apkFile.getName(), 0, sizeBytes, pfd);
}
} catch (IOException e) {
Slog.e(TAG, "Failure to install APK staged session " + originalSession.sessionId, e);
- return null;
+ throw new PackageManagerException(errorCode, "Failed to write APK session", e);
}
return apkSession;
}
- private boolean commitApkSession(@NonNull PackageInstallerSession apkSession,
- int originalSessionId, boolean preReboot) {
-
+ private void commitApkSession(@NonNull PackageInstallerSession apkSession,
+ int originalSessionId, boolean preReboot) throws PackageManagerException {
+ final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
+ : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
if (!preReboot) {
if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
// If rollback is available for this session, notify the rollback
@@ -457,23 +465,24 @@ public class StagingManager {
final Intent result = receiver.getResult();
final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);
- if (status == PackageInstaller.STATUS_SUCCESS) {
- return true;
+ if (status != PackageInstaller.STATUS_SUCCESS) {
+
+ final String errorMessage = result.getStringExtra(
+ PackageInstaller.EXTRA_STATUS_MESSAGE);
+ Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " ["
+ + errorMessage + "]");
+ throw new PackageManagerException(errorCode, errorMessage);
}
- Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " ["
- + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
- return false;
}
- private boolean installApksInSession(@NonNull PackageInstallerSession session,
- boolean preReboot) {
+ private void installApksInSession(@NonNull PackageInstallerSession session,
+ boolean preReboot) throws PackageManagerException {
+ final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED
+ : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED;
if (!session.isMultiPackage() && !isApexSession(session)) {
// APK single-packaged staged session. Do a regular install.
PackageInstallerSession apkSession = createAndWriteApkSession(session, preReboot);
- if (apkSession == null) {
- return false;
- }
- return commitApkSession(apkSession, session.sessionId, preReboot);
+ commitApkSession(apkSession, session.sessionId, preReboot);
} else if (session.isMultiPackage()) {
// For multi-package staged sessions containing APKs, we identify which child sessions
// contain an APK, and with those then create a new multi-package group of sessions,
@@ -491,7 +500,7 @@ public class StagingManager {
}
if (childSessions.isEmpty()) {
// APEX-only multi-package staged session, nothing to do.
- return true;
+ return;
}
PackageInstaller.SessionParams params = session.params.copy();
params.isStaged = false;
@@ -508,26 +517,24 @@ public class StagingManager {
} catch (IOException e) {
Slog.e(TAG, "Unable to prepare multi-package session for staged session "
+ session.sessionId);
- return false;
+ throw new PackageManagerException(errorCode,
+ "Unable to prepare multi-package session for staged session");
}
for (PackageInstallerSession sessionToClone : childSessions) {
PackageInstallerSession apkChildSession =
createAndWriteApkSession(sessionToClone, preReboot);
- if (apkChildSession == null) {
- return false;
- }
try {
apkParentSession.addChildSessionId(apkChildSession.sessionId);
} catch (IllegalStateException e) {
Slog.e(TAG, "Failed to add a child session for installing the APK files", e);
- return false;
+ throw new PackageManagerException(errorCode,
+ "Failed to add a child session " + apkChildSession.sessionId);
}
}
- return commitApkSession(apkParentSession, session.sessionId, preReboot);
+ commitApkSession(apkParentSession, session.sessionId, preReboot);
}
// APEX single-package staged session, nothing to do.
- return true;
}
void commitSession(@NonNull PackageInstallerSession session) {