Loading core/java/android/os/ExternalVibration.java +0 −1 Original line number Diff line number Diff line Loading @@ -157,7 +157,6 @@ public class ExternalVibration implements Parcelable { out.writeInt(mUid); out.writeString(mPkg); writeAudioAttributes(mAttrs, out, flags); out.writeParcelable(mAttrs, flags); out.writeStrongBinder(mController.asBinder()); out.writeStrongBinder(mToken); } Loading core/tests/coretests/src/android/os/ExternalVibrationTest.java 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.os; import static junit.framework.Assert.assertEquals; import static org.mockito.Mockito.mock; import android.media.AudioAttributes; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ExternalVibrationTest { @Test public void testSerialization() { AudioAttributes audio = new AudioAttributes.Builder().build(); IExternalVibrationController controller = mock(IExternalVibrationController.class); ExternalVibration original = new ExternalVibration( 123, // uid "pkg", audio, controller); Parcel p = Parcel.obtain(); original.writeToParcel(p, 0); p.setDataPosition(0); ExternalVibration restored = ExternalVibration.CREATOR.createFromParcel(p); assertEquals(original, restored); } } services/core/java/com/android/server/appop/AppOpsService.java +71 −18 Original line number Diff line number Diff line Loading @@ -31,10 +31,13 @@ import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION; import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_PERSISTENT; import static android.app.AppOpsManager.UID_STATE_TOP; import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES; import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; import static java.lang.Long.max; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -933,6 +936,19 @@ public class AppOpsService extends IAppOpsService.Stub { } } /** * Update the pending state for the uid * * @param currentTime The current elapsed real time * @param uid The uid that has a pending state */ private void updatePendingState(long currentTime, int uid) { synchronized (this) { mLastRealtime = max(currentTime, mLastRealtime); updatePendingStateIfNeededLocked(mUidStates.get(uid)); } } public void updateUidProcState(int uid, int procState) { synchronized (this) { final UidState uidState = getUidStateLocked(uid, true); Loading @@ -958,7 +974,12 @@ public class AppOpsService extends IAppOpsService.Stub { } else { settleTime = mConstants.BG_STATE_SETTLE_TIME; } uidState.pendingStateCommitTime = SystemClock.elapsedRealtime() + settleTime; final long commitTime = SystemClock.elapsedRealtime() + settleTime; uidState.pendingStateCommitTime = commitTime; mHandler.sendMessageDelayed( PooledLambda.obtainMessage(AppOpsService::updatePendingState, this, commitTime + 1, uid), settleTime + 1); } if (uidState.startNesting != 0) { // There is some actively running operation... need to find it Loading Loading @@ -1288,6 +1309,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.evalForegroundOps(mOpModeWatchers); } notifyOpChangedForAllPkgsInUid(code, uid, false); notifyOpChangedSync(code, uid, null, mode); } /** * Notify that an op changed for all packages in an uid. * * @param code The op that changed * @param uid The uid the op was changed for * @param onlyForeground Only notify watchers that watch for foreground changes */ private void notifyOpChangedForAllPkgsInUid(int code, int uid, boolean onlyForeground) { String[] uidPackageNames = getPackagesForUid(uid); ArrayMap<ModeCallback, ArraySet<String>> callbackSpecs = null; Loading @@ -1297,6 +1330,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { ModeCallback callback = callbacks.valueAt(i); if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) { continue; } ArraySet<String> changedPackages = new ArraySet<>(); Collections.addAll(changedPackages, uidPackageNames); if (callbackSpecs == null) { Loading @@ -1315,6 +1352,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { ModeCallback callback = callbacks.valueAt(i); if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) { continue; } ArraySet<String> changedPackages = callbackSpecs.get(callback); if (changedPackages == null) { changedPackages = new ArraySet<>(); Loading @@ -1327,7 +1368,6 @@ public class AppOpsService extends IAppOpsService.Stub { } if (callbackSpecs == null) { notifyOpChangedSync(code, uid, null, mode); return; } Loading @@ -1349,8 +1389,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } notifyOpChangedSync(code, uid, null, mode); } private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) { Loading Loading @@ -2467,6 +2505,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState = new UidState(uid); mUidStates.put(uid, uidState); } else { updatePendingStateIfNeededLocked(uidState); } return uidState; } /** * Check if the pending state should be updated and do so if needed * * @param uidState The uidState that might have a pending state */ private void updatePendingStateIfNeededLocked(@NonNull UidState uidState) { if (uidState != null) { if (uidState.pendingStateCommitTime != 0) { if (uidState.pendingStateCommitTime < mLastRealtime) { commitUidPendingStateLocked(uidState); Loading @@ -2478,7 +2528,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } return uidState; } private void commitUidPendingStateLocked(UidState uidState) { Loading @@ -2496,6 +2545,14 @@ public class AppOpsService extends IAppOpsService.Stub { if (resolvedLastFg == resolvedNowFg) { continue; } if (uidState.opModes != null && uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND) { mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::notifyOpChangedForAllPkgsInUid, this, code, uidState.uid, true)); } else { final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code); if (callbacks != null) { for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) { Loading @@ -2504,16 +2561,12 @@ public class AppOpsService extends IAppOpsService.Stub { || !callback.isWatchingUid(uidState.uid)) { continue; } boolean doAllPackages = uidState.opModes != null && uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND; if (uidState.pkgOps != null) { for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) { final Op op = uidState.pkgOps.valueAt(pkgi).get(code); if (op == null) { continue; } if (doAllPackages || op.mode == AppOpsManager.MODE_FOREGROUND) { if (op.mode == AppOpsManager.MODE_FOREGROUND) { mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::notifyOpChanged, this, callback, code, uidState.uid, Loading services/core/java/com/android/server/pm/PackageInstallerService.java +6 −3 Original line number Diff line number Diff line Loading @@ -258,12 +258,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } // Don't hold mSessions lock when calling restoreSession, since it might trigger an APK // atomic install which needs to query sessions, which requires lock on mSessions. boolean isDeviceUpgrading = mPm.isDeviceUpgrading(); for (PackageInstallerSession session : stagedSessionsToRestore) { if (mPm.isDeviceUpgrading() && !session.isStagedAndInTerminalState()) { if (!session.isStagedAndInTerminalState() && session.hasParentSessionId() && getSession(session.getParentSessionId()) == null) { session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, "Build fingerprint has changed"); "An orphan staged session " + session.sessionId + " is found, " + "parent " + session.getParentSessionId() + " is missing"); } mStagingManager.restoreSession(session); mStagingManager.restoreSession(session, isDeviceUpgrading); } // Broadcasts are not sent while we restore sessions on boot, since no processes would be // ready to listen to them. From now on, we greedily assume that broadcasts requests are Loading services/core/java/com/android/server/pm/StagingManager.java +8 −1 Original line number Diff line number Diff line Loading @@ -619,7 +619,7 @@ public class StagingManager { return false; } void restoreSession(@NonNull PackageInstallerSession session) { void restoreSession(@NonNull PackageInstallerSession session, boolean isDeviceUpgrading) { PackageInstallerSession sessionToResume = session; synchronized (mStagedSessions) { mStagedSessions.append(session.sessionId, session); Loading @@ -636,6 +636,13 @@ public class StagingManager { } } } // The preconditions used during pre-reboot verification might have changed when device // is upgrading. Updated staged sessions to activation failed before we resume the session. if (isDeviceUpgrading && !sessionToResume.isStagedAndInTerminalState()) { sessionToResume.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, "Build fingerprint has changed"); return; } checkStateAndResume(sessionToResume); } Loading Loading
core/java/android/os/ExternalVibration.java +0 −1 Original line number Diff line number Diff line Loading @@ -157,7 +157,6 @@ public class ExternalVibration implements Parcelable { out.writeInt(mUid); out.writeString(mPkg); writeAudioAttributes(mAttrs, out, flags); out.writeParcelable(mAttrs, flags); out.writeStrongBinder(mController.asBinder()); out.writeStrongBinder(mToken); } Loading
core/tests/coretests/src/android/os/ExternalVibrationTest.java 0 → 100644 +47 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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.os; import static junit.framework.Assert.assertEquals; import static org.mockito.Mockito.mock; import android.media.AudioAttributes; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class ExternalVibrationTest { @Test public void testSerialization() { AudioAttributes audio = new AudioAttributes.Builder().build(); IExternalVibrationController controller = mock(IExternalVibrationController.class); ExternalVibration original = new ExternalVibration( 123, // uid "pkg", audio, controller); Parcel p = Parcel.obtain(); original.writeToParcel(p, 0); p.setDataPosition(0); ExternalVibration restored = ExternalVibration.CREATOR.createFromParcel(p); assertEquals(original, restored); } }
services/core/java/com/android/server/appop/AppOpsService.java +71 −18 Original line number Diff line number Diff line Loading @@ -31,10 +31,13 @@ import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION; import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED; import static android.app.AppOpsManager.UID_STATE_PERSISTENT; import static android.app.AppOpsManager.UID_STATE_TOP; import static android.app.AppOpsManager.WATCH_FOREGROUND_CHANGES; import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; import static java.lang.Long.max; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -933,6 +936,19 @@ public class AppOpsService extends IAppOpsService.Stub { } } /** * Update the pending state for the uid * * @param currentTime The current elapsed real time * @param uid The uid that has a pending state */ private void updatePendingState(long currentTime, int uid) { synchronized (this) { mLastRealtime = max(currentTime, mLastRealtime); updatePendingStateIfNeededLocked(mUidStates.get(uid)); } } public void updateUidProcState(int uid, int procState) { synchronized (this) { final UidState uidState = getUidStateLocked(uid, true); Loading @@ -958,7 +974,12 @@ public class AppOpsService extends IAppOpsService.Stub { } else { settleTime = mConstants.BG_STATE_SETTLE_TIME; } uidState.pendingStateCommitTime = SystemClock.elapsedRealtime() + settleTime; final long commitTime = SystemClock.elapsedRealtime() + settleTime; uidState.pendingStateCommitTime = commitTime; mHandler.sendMessageDelayed( PooledLambda.obtainMessage(AppOpsService::updatePendingState, this, commitTime + 1, uid), settleTime + 1); } if (uidState.startNesting != 0) { // There is some actively running operation... need to find it Loading Loading @@ -1288,6 +1309,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.evalForegroundOps(mOpModeWatchers); } notifyOpChangedForAllPkgsInUid(code, uid, false); notifyOpChangedSync(code, uid, null, mode); } /** * Notify that an op changed for all packages in an uid. * * @param code The op that changed * @param uid The uid the op was changed for * @param onlyForeground Only notify watchers that watch for foreground changes */ private void notifyOpChangedForAllPkgsInUid(int code, int uid, boolean onlyForeground) { String[] uidPackageNames = getPackagesForUid(uid); ArrayMap<ModeCallback, ArraySet<String>> callbackSpecs = null; Loading @@ -1297,6 +1330,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { ModeCallback callback = callbacks.valueAt(i); if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) { continue; } ArraySet<String> changedPackages = new ArraySet<>(); Collections.addAll(changedPackages, uidPackageNames); if (callbackSpecs == null) { Loading @@ -1315,6 +1352,10 @@ public class AppOpsService extends IAppOpsService.Stub { final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { ModeCallback callback = callbacks.valueAt(i); if (onlyForeground && (callback.mFlags & WATCH_FOREGROUND_CHANGES) == 0) { continue; } ArraySet<String> changedPackages = callbackSpecs.get(callback); if (changedPackages == null) { changedPackages = new ArraySet<>(); Loading @@ -1327,7 +1368,6 @@ public class AppOpsService extends IAppOpsService.Stub { } if (callbackSpecs == null) { notifyOpChangedSync(code, uid, null, mode); return; } Loading @@ -1349,8 +1389,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } notifyOpChangedSync(code, uid, null, mode); } private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode) { Loading Loading @@ -2467,6 +2505,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState = new UidState(uid); mUidStates.put(uid, uidState); } else { updatePendingStateIfNeededLocked(uidState); } return uidState; } /** * Check if the pending state should be updated and do so if needed * * @param uidState The uidState that might have a pending state */ private void updatePendingStateIfNeededLocked(@NonNull UidState uidState) { if (uidState != null) { if (uidState.pendingStateCommitTime != 0) { if (uidState.pendingStateCommitTime < mLastRealtime) { commitUidPendingStateLocked(uidState); Loading @@ -2478,7 +2528,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } return uidState; } private void commitUidPendingStateLocked(UidState uidState) { Loading @@ -2496,6 +2545,14 @@ public class AppOpsService extends IAppOpsService.Stub { if (resolvedLastFg == resolvedNowFg) { continue; } if (uidState.opModes != null && uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND) { mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::notifyOpChangedForAllPkgsInUid, this, code, uidState.uid, true)); } else { final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code); if (callbacks != null) { for (int cbi = callbacks.size() - 1; cbi >= 0; cbi--) { Loading @@ -2504,16 +2561,12 @@ public class AppOpsService extends IAppOpsService.Stub { || !callback.isWatchingUid(uidState.uid)) { continue; } boolean doAllPackages = uidState.opModes != null && uidState.opModes.indexOfKey(code) >= 0 && uidState.opModes.get(code) == AppOpsManager.MODE_FOREGROUND; if (uidState.pkgOps != null) { for (int pkgi = uidState.pkgOps.size() - 1; pkgi >= 0; pkgi--) { final Op op = uidState.pkgOps.valueAt(pkgi).get(code); if (op == null) { continue; } if (doAllPackages || op.mode == AppOpsManager.MODE_FOREGROUND) { if (op.mode == AppOpsManager.MODE_FOREGROUND) { mHandler.sendMessage(PooledLambda.obtainMessage( AppOpsService::notifyOpChanged, this, callback, code, uidState.uid, Loading
services/core/java/com/android/server/pm/PackageInstallerService.java +6 −3 Original line number Diff line number Diff line Loading @@ -258,12 +258,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements } // Don't hold mSessions lock when calling restoreSession, since it might trigger an APK // atomic install which needs to query sessions, which requires lock on mSessions. boolean isDeviceUpgrading = mPm.isDeviceUpgrading(); for (PackageInstallerSession session : stagedSessionsToRestore) { if (mPm.isDeviceUpgrading() && !session.isStagedAndInTerminalState()) { if (!session.isStagedAndInTerminalState() && session.hasParentSessionId() && getSession(session.getParentSessionId()) == null) { session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, "Build fingerprint has changed"); "An orphan staged session " + session.sessionId + " is found, " + "parent " + session.getParentSessionId() + " is missing"); } mStagingManager.restoreSession(session); mStagingManager.restoreSession(session, isDeviceUpgrading); } // Broadcasts are not sent while we restore sessions on boot, since no processes would be // ready to listen to them. From now on, we greedily assume that broadcasts requests are Loading
services/core/java/com/android/server/pm/StagingManager.java +8 −1 Original line number Diff line number Diff line Loading @@ -619,7 +619,7 @@ public class StagingManager { return false; } void restoreSession(@NonNull PackageInstallerSession session) { void restoreSession(@NonNull PackageInstallerSession session, boolean isDeviceUpgrading) { PackageInstallerSession sessionToResume = session; synchronized (mStagedSessions) { mStagedSessions.append(session.sessionId, session); Loading @@ -636,6 +636,13 @@ public class StagingManager { } } } // The preconditions used during pre-reboot verification might have changed when device // is upgrading. Updated staged sessions to activation failed before we resume the session. if (isDeviceUpgrading && !sessionToResume.isStagedAndInTerminalState()) { sessionToResume.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED, "Build fingerprint has changed"); return; } checkStateAndResume(sessionToResume); } Loading