summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/display/DisplayManager.java9
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/PasswordTextView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/RoundedCorners.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java6
-rw-r--r--services/core/java/com/android/server/audio/PlaybackActivityMonitor.java16
-rw-r--r--services/core/java/com/android/server/display/DisplayManagerService.java12
-rw-r--r--services/core/java/com/android/server/display/VirtualDisplayAdapter.java5
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java74
-rw-r--r--services/core/java/com/android/server/vr/Vr2dDisplay.java1
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java83
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java27
14 files changed, 185 insertions, 70 deletions
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 6a02b6b2e6e7..bda80390a614 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -256,6 +256,15 @@ public final class DisplayManager {
*/
public static final int VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH = 1 << 6;
+ /**
+ * Virtual display flag: Indicates that the orientation of this display device is coupled to
+ * the rotation of its associated logical display.
+ *
+ * @see #createVirtualDisplay
+ * @hide
+ */
+ public static final int VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT = 1 << 7;
+
/** @hide */
public DisplayManager(Context context) {
mContext = context;
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 72023ce058a5..1614efbd6b65 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3052,6 +3052,8 @@
<java-symbol type="drawable" name="stat_sys_vitals" />
+ <java-symbol type="color" name="text_color_primary" />
+
<java-symbol type="array" name="config_batteryPackageTypeSystem" />
<java-symbol type="array" name="config_batteryPackageTypeService" />
<java-symbol type="bool" name="config_showAreaUpdateInfoSettings" />
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index d8bebabf0c5e..12f75bb2d56c 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -29,10 +29,8 @@ import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.PowerManager;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.provider.Settings;
import android.text.InputType;
-import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
@@ -252,9 +250,9 @@ public class PasswordTextView extends View {
mText = mText.substring(0, length - 1);
CharState charState = mTextChars.get(length - 1);
charState.startRemoveAnimation(0, 0);
+ sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
}
userActivity();
- sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
}
public String getText() {
diff --git a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
index 6397eb5d756b..61325400846a 100644
--- a/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
+++ b/packages/SystemUI/src/com/android/systemui/RoundedCorners.java
@@ -98,9 +98,13 @@ public class RoundedCorners extends SystemUI implements Tunable {
TunablePadding.addTunablePadding(statusBar.findViewById(R.id.keyguard_header), PADDING,
padding, FLAG_END);
- FragmentHostManager.get(sb.getNavigationBarWindow()).addTagListener(
+ View navigationBarWindow = sb.getNavigationBarWindow();
+ // Not all devices have on screen navigation bars.
+ if (navigationBarWindow != null) {
+ FragmentHostManager.get(navigationBarWindow).addTagListener(
NavigationBarFragment.TAG,
new TunablePaddingTagListener(padding, 0));
+ }
FragmentHostManager fragmentHostManager = FragmentHostManager.get(statusBar);
fragmentHostManager.addTagListener(CollapsedStatusBarFragment.TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index 5a163d4d56c2..f8591247f1d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -417,7 +417,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
@Override
public void onHeightUpdate() {
- if (mParent == null || mMenuItems.size() == 0) {
+ if (mParent == null || mMenuItems.size() == 0 || mMenuContainer == null) {
return;
}
int parentHeight = mParent.getCollapsedHeight();
@@ -477,7 +477,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
private void setMenuLocation() {
boolean showOnLeft = mTranslation > 0;
- if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping
+ if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping || mMenuContainer == null
|| !mMenuContainer.isAttachedToWindow()) {
// Do nothing
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 419aefe3e9e9..754c34486954 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -61,11 +61,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
public static final float GRADIENT_SCRIM_ALPHA = 0.45f;
// A scrim varies its opacity based on a busyness factor, for example
// how many notifications are currently visible.
- public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.90f;
+ public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
- private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA;
- private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA;
+ private static final float SCRIM_IN_FRONT_ALPHA = GRADIENT_SCRIM_ALPHA_BUSY;
+ private static final float SCRIM_IN_FRONT_ALPHA_LOCKED = GRADIENT_SCRIM_ALPHA_BUSY;
private static final int TAG_KEY_ANIM = R.id.scrim;
private static final int TAG_KEY_ANIM_TARGET = R.id.scrim_target;
private static final int TAG_START_ALPHA = R.id.scrim_alpha_start;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
index 630da2e7eabc..2a2acabc8cee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -57,4 +57,10 @@ public class NotificationMenuRowTest extends LeakCheckedTest {
row.createMenu(null, null);
assertTrue(row.getMenuView() != null);
}
+
+ @Test
+ public void testResetUncreatedMenu() {
+ NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
+ row.resetMenu();
+ }
}
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 702cbbed17de..f9e4d946a178 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -29,6 +29,8 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.util.ArrayUtils;
+
import java.io.PrintWriter;
import java.text.DateFormat;
import java.util.ArrayList;
@@ -67,6 +69,12 @@ public final class PlaybackActivityMonitor
.createIfNeeded()
.build();
+ // TODO support VolumeShaper on those players
+ private static final int[] UNDUCKABLE_PLAYER_TYPES = {
+ AudioPlaybackConfiguration.PLAYER_TYPE_AAUDIO,
+ AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL,
+ };
+
// like a PLAY_CREATE_IF_NEEDED operation but with a skip to the end of the ramp
private static final VolumeShaper.Operation PLAY_SKIP_RAMP =
new VolumeShaper.Operation.Builder(PLAY_CREATE_IF_NEEDED).setXOffset(1.0f).build();
@@ -298,12 +306,12 @@ public final class PlaybackActivityMonitor
+ " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
+ " - SPEECH");
return false;
- } else if (apc.getPlayerType()
- == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
- // TODO support ducking of SoundPool players
+ } else if (ArrayUtils.contains(UNDUCKABLE_PLAYER_TYPES, apc.getPlayerType())) {
Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
+ " uid:" + apc.getClientUid() + " pid:" + apc.getClientPid()
- + " - SoundPool");
+ + " due to type:"
+ + AudioPlaybackConfiguration.toLogFriendlyPlayerType(
+ apc.getPlayerType()));
return false;
}
apcsToDuck.add(apc);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 8129f450a85b..ab3aff99937d 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1221,6 +1221,18 @@ public final class DisplayManagerService extends SystemService {
}
}
+ @VisibleForTesting
+ DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) {
+ synchronized (mSyncRoot) {
+ LogicalDisplay display = mLogicalDisplays.get(displayId);
+ if (display != null) {
+ DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked();
+ return displayDevice.getDisplayDeviceInfoLocked();
+ }
+ return null;
+ }
+ }
+
private final class DisplayManagerHandler extends Handler {
public DisplayManagerHandler(Looper looper) {
super(looper, null, true /*async*/);
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 9d3021af1ac2..d6ab88813f4d 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -23,6 +23,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESE
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
import android.content.Context;
import android.hardware.display.IVirtualDisplayCallback;
@@ -359,6 +360,10 @@ public class VirtualDisplayAdapter extends DisplayAdapter {
if ((mFlags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
mInfo.flags |= DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
}
+ if ((mFlags & VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT) != 0) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+ }
+
mInfo.type = Display.TYPE_VIRTUAL;
mInfo.touch = ((mFlags & VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH) == 0) ?
DisplayDeviceInfo.TOUCH_NONE : DisplayDeviceInfo.TOUCH_VIRTUAL;
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index fe2c5bd87df4..c1e820c9b787 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -142,6 +142,7 @@ public class LockSettingsService extends ILockSettings.Stub {
private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
// Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
+ // Do not call into ActivityManager while holding mSpManager lock.
private final Object mSeparateChallengeLock = new Object();
private final DeviceProvisionedObserver mDeviceProvisionedObserver =
@@ -1434,16 +1435,14 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.e(TAG, "FRP credential can only be verified prior to provisioning.");
return VerifyCredentialResponse.ERROR;
}
- synchronized (mSpManager) {
- if (isSyntheticPasswordBasedCredentialLocked(userId)) {
- VerifyCredentialResponse response = spBasedDoVerifyCredentialLocked(credential,
- credentialType, hasChallenge, challenge, userId, progressCallback);
- if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
- mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
- }
- return response;
- }
+ VerifyCredentialResponse response = null;
+ response = spBasedDoVerifyCredential(credential, credentialType, hasChallenge, challenge,
+ userId, progressCallback);
+ // The user employs synthetic password based credential.
+ if (response != null) {
+ return response;
}
+
final CredentialHash storedHash;
if (userId == USER_FRP) {
PersistentData data = mStorage.readPersistentDataBlock();
@@ -1472,7 +1471,7 @@ public class LockSettingsService extends ILockSettings.Stub {
credentialToVerify = credential;
}
- VerifyCredentialResponse response = verifyCredential(userId, storedHash, credentialToVerify,
+ response = verifyCredential(userId, storedHash, credentialToVerify,
hasChallenge, challenge, progressCallback);
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
@@ -1995,33 +1994,46 @@ public class LockSettingsService extends ILockSettings.Stub {
setLong(SYNTHETIC_PASSWORD_ENABLED_KEY, 1, UserHandle.USER_SYSTEM);
}
- private VerifyCredentialResponse spBasedDoVerifyCredentialLocked(String userCredential, int
+ private VerifyCredentialResponse spBasedDoVerifyCredential(String userCredential, int
credentialType, boolean hasChallenge, long challenge, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
- if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredentialLocked: user=" + userId);
+ if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
if (credentialType == LockPatternUtils.CREDENTIAL_TYPE_NONE) {
userCredential = null;
}
- if (userId == USER_FRP) {
- return mSpManager.verifyFrpCredential(getGateKeeperService(),
- userCredential, credentialType, progressCallback);
- }
- long handle = getSyntheticPasswordHandleLocked(userId);
- AuthenticationResult authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
- getGateKeeperService(), handle, userCredential, userId);
+ final AuthenticationResult authResult;
+ VerifyCredentialResponse response;
+ synchronized (mSpManager) {
+ if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
+ return null;
+ }
+ if (userId == USER_FRP) {
+ return mSpManager.verifyFrpCredential(getGateKeeperService(),
+ userCredential, credentialType, progressCallback);
+ }
- VerifyCredentialResponse response = authResult.gkResponse;
- if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+ long handle = getSyntheticPasswordHandleLocked(userId);
+ authResult = mSpManager.unwrapPasswordBasedSyntheticPassword(
+ getGateKeeperService(), handle, userCredential, userId);
+
+ response = authResult.gkResponse;
// credential has matched
- // perform verifyChallenge with synthetic password which generates the real auth
- // token for the current user
- response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
- challenge, userId);
- if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
- Slog.wtf(TAG, "verifyChallenge with SP failed.");
- return VerifyCredentialResponse.ERROR;
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
+ // perform verifyChallenge with synthetic password which generates the real GK auth
+ // token and response for the current user
+ response = mSpManager.verifyChallenge(getGateKeeperService(), authResult.authToken,
+ challenge, userId);
+ if (response.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) {
+ // This shouldn't really happen: the unwrapping of SP succeeds, but SP doesn't
+ // match the recorded GK password handle.
+ Slog.wtf(TAG, "verifyChallenge with SP failed.");
+ return VerifyCredentialResponse.ERROR;
+ }
}
+ }
+
+ if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
if (progressCallback != null) {
progressCallback.onCredentialVerified();
}
@@ -2032,12 +2044,14 @@ public class LockSettingsService extends ILockSettings.Stub {
Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
unlockUser(userId, null, secret);
+ activateEscrowTokens(authResult.authToken, userId);
+
if (isManagedProfileWithSeparatedLock(userId)) {
TrustManager trustManager =
(TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
trustManager.setDeviceLockedForUser(userId, false);
}
- activateEscrowTokens(authResult.authToken, userId);
+ mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
} else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) {
if (response.getTimeout() > 0) {
requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
@@ -2184,8 +2198,8 @@ public class LockSettingsService extends ILockSettings.Stub {
private void activateEscrowTokens(AuthenticationToken auth, int userId) throws RemoteException {
if (DEBUG) Slog.d(TAG, "activateEscrowTokens: user=" + userId);
- disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
synchronized (mSpManager) {
+ disableEscrowTokenOnNonManagedDevicesIfNeeded(userId);
for (long handle : mSpManager.getPendingTokensForUser(userId)) {
Slog.i(TAG, String.format("activateEscrowTokens: %x %d ", handle, userId));
mSpManager.activateTokenBasedSyntheticPassword(handle, auth, userId);
diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java
index 4a1297f8af71..8335243d590f 100644
--- a/services/core/java/com/android/server/vr/Vr2dDisplay.java
+++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java
@@ -266,6 +266,7 @@ class Vr2dDisplay {
}
int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
+ flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
null /* surface */, flags, null /* callback */, null /* handler */,
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 70c7e586d3fe..608635491849 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -25,8 +25,8 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
-import android.util.Log;
import android.util.LongSparseArray;
+import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -60,16 +60,21 @@ final class NetworkLoggingHandler extends Handler {
/** Delay after which older batches get discarded after a retrieval. */
private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m
+ /** Do not call into mDpm with locks held */
private final DevicePolicyManagerService mDpm;
private final AlarmManager mAlarmManager;
private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() {
@Override
public void onAlarm() {
- Log.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+ Slog.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+ mNetworkEvents.size() + " pending events.");
+ Bundle notificationExtras = null;
synchronized (NetworkLoggingHandler.this) {
- finalizeBatchAndNotifyDeviceOwnerLocked();
+ notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
+ }
+ if (notificationExtras != null) {
+ notifyDeviceOwner(notificationExtras);
}
}
};
@@ -110,17 +115,21 @@ final class NetworkLoggingHandler extends Handler {
case LOG_NETWORK_EVENT_MSG: {
final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
if (networkEvent != null) {
+ Bundle notificationExtras = null;
synchronized (NetworkLoggingHandler.this) {
mNetworkEvents.add(networkEvent);
if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) {
- finalizeBatchAndNotifyDeviceOwnerLocked();
+ notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
}
}
+ if (notificationExtras != null) {
+ notifyDeviceOwner(notificationExtras);
+ }
}
break;
}
default: {
- Log.d(TAG, "NetworkLoggingHandler received an unknown of message.");
+ Slog.d(TAG, "NetworkLoggingHandler received an unknown of message.");
break;
}
}
@@ -133,40 +142,48 @@ final class NetworkLoggingHandler extends Handler {
mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
mBatchTimeoutAlarmListener, this);
- Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+ Slog.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+ "ms from now.");
}
synchronized void pause() {
- Log.d(TAG, "Paused network logging");
+ Slog.d(TAG, "Paused network logging");
mPaused = true;
}
- synchronized void resume() {
- if (!mPaused) {
- Log.d(TAG, "Attempted to resume network logging, but logging is not paused.");
- return;
- }
+ void resume() {
+ Bundle notificationExtras = null;
+ synchronized (this) {
+ if (!mPaused) {
+ Slog.d(TAG, "Attempted to resume network logging, but logging is not paused.");
+ return;
+ }
- Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
- + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
- mPaused = false;
+ Slog.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
+ + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
+ mPaused = false;
- // If there is a batch ready that the device owner hasn't been notified about, do it now.
- if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
- scheduleBatchFinalization();
- notifyDeviceOwnerLocked();
+ // If there is a batch ready that the device owner hasn't been notified about, do it now.
+ if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
+ scheduleBatchFinalization();
+ notificationExtras = buildDeviceOwnerMessageLocked();
+ }
+ }
+ if (notificationExtras != null) {
+ notifyDeviceOwner(notificationExtras);
}
}
synchronized void discardLogs() {
mBatches.clear();
mNetworkEvents = new ArrayList<>();
- Log.d(TAG, "Discarded all network logs");
+ Slog.d(TAG, "Discarded all network logs");
}
@GuardedBy("this")
- private void finalizeBatchAndNotifyDeviceOwnerLocked() {
+ /** @returns extras if a message should be sent to the device owner */
+ private Bundle finalizeBatchAndBuildDeviceOwnerMessageLocked() {
+ Bundle notificationExtras = null;
if (mNetworkEvents.size() > 0) {
// Finalize the batch and start a new one from scratch.
if (mBatches.size() >= MAX_BATCHES) {
@@ -177,27 +194,39 @@ final class NetworkLoggingHandler extends Handler {
mBatches.append(mCurrentBatchToken, mNetworkEvents);
mNetworkEvents = new ArrayList<>();
if (!mPaused) {
- notifyDeviceOwnerLocked();
+ notificationExtras = buildDeviceOwnerMessageLocked();
}
} else {
// Don't notify the DO, since there are no events; DPC can still retrieve
// the last full batch if not paused.
- Log.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+ Slog.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+ " the DPC, the batchToken of last available batch: " + mCurrentBatchToken);
}
// Regardless of whether the batch was non-empty schedule a new finalization after timeout.
scheduleBatchFinalization();
+ return notificationExtras;
}
- /** Sends a notification to the DO. Should only be called when there is a batch available. */
@GuardedBy("this")
- private void notifyDeviceOwnerLocked() {
+ /** Build extras notification to the DO. Should only be called when there
+ is a batch available. */
+ private Bundle buildDeviceOwnerMessageLocked() {
final Bundle extras = new Bundle();
final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size();
extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken);
extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize);
- Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
- + mCurrentBatchToken);
+ return extras;
+ }
+
+ /** Sends a notification to the DO. Should not hold locks as DevicePolicyManagerService may
+ call into NetworkLoggingHandler. */
+ private void notifyDeviceOwner(Bundle extras) {
+ Slog.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
+ + extras.getLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, -1));
+ if (Thread.holdsLock(this)) {
+ Slog.wtfStack(TAG, "Shouldn't be called with NetworkLoggingHandler lock held");
+ return;
+ }
mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
}
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index c399a5de46dd..e3ce17bcd2d8 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -29,6 +29,7 @@ import android.view.SurfaceControl;
import android.view.WindowManagerInternal;
import com.android.server.LocalServices;
+import com.android.server.display.DisplayDeviceInfo;
import com.android.server.display.DisplayManagerService.SyncRoot;
import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory;
@@ -115,4 +116,30 @@ public class DisplayManagerServiceTest extends AndroidTestCase {
assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId);
assertEquals(displayId, dv.displayId);
}
+
+ public void testCreateVirtualDisplayRotatesWithContent() throws Exception {
+ // This is effectively the DisplayManager service published to ServiceManager.
+ DisplayManagerService.BinderService bs = mDisplayManager.new BinderService();
+
+ String uniqueId = "uniqueId --- Rotates With Content Test";
+ int width = 600;
+ int height = 800;
+ int dpi = 320;
+ int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
+
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+ int displayId = bs.createVirtualDisplay(mMockAppToken /* callback */,
+ null /* projection */, "com.android.frameworks.servicestests",
+ "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */,
+ uniqueId);
+
+ mDisplayManager.performTraversalInTransactionFromWindowManagerInternal();
+
+ // flush the handler
+ mHandler.runWithScissors(() -> {}, 0 /* now */);
+
+ DisplayDeviceInfo ddi = mDisplayManager.getDisplayDeviceInfoInternal(displayId);
+ assertNotNull(ddi);
+ assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0);
+ }
}