diff options
Diffstat (limited to 'services/java')
8 files changed, 189 insertions, 79 deletions
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index ad1dfb2..a7c4d73 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -2686,18 +2686,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { state + "/" + info.getDetailedState()); } - // Connectivity state changed: - // [31-14] Reserved for future use - // [13-10] Network subtype (for mobile network, as defined - // by TelephonyManager) - // [9-4] Detailed state ordinal (as defined by - // NetworkInfo.DetailedState) - // [3-0] Network type (as defined by ConnectivityManager) - int eventLogParam = (info.getType() & 0xf) | - ((info.getDetailedState().ordinal() & 0x3f) << 4) | - (info.getSubtype() << 10); - EventLog.writeEvent(EventLogTags.CONNECTIVITY_STATE_CHANGED, - eventLogParam); + EventLogTags.writeConnectivityStateChanged( + info.getType(), info.getSubtype(), info.getDetailedState().ordinal()); if (info.getDetailedState() == NetworkInfo.DetailedState.FAILED) { diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags index 0fe66fc..8bc2da2 100644 --- a/services/java/com/android/server/EventLogTags.logtags +++ b/services/java/com/android/server/EventLogTags.logtags @@ -135,12 +135,8 @@ option java_package com.android.server # --------------------------- # ConnectivityService.java # --------------------------- -# Connectivity state changed: -# [31-14] Reserved for future use -# [13-10] Network subtype (for mobile network, as defined by TelephonyManager) -# [ 9- 4] Detailed state ordinal (as defined by NetworkInfo.DetailedState) -# [ 3- 0] Network type (as defined by ConnectivityManager) -50020 connectivity_state_changed (custom|1|5) +# Connectivity state changed +50020 connectivity_state_changed (type|1),(subtype|1),(state|1) # --------------------------- diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index d2cd646..db64a9a 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -14229,6 +14229,7 @@ public final class ActivityManagerService extends ActivityManagerNative startHomeActivityLocked(userId); } + EventLogTags.writeAmSwitchUser(userId); getUserManagerLocked().userForeground(userId); sendUserSwitchBroadcastsLocked(oldUserId, userId); if (needStart) { diff --git a/services/java/com/android/server/am/EventLogTags.logtags b/services/java/com/android/server/am/EventLogTags.logtags index 6ee7507..88c0c03 100644 --- a/services/java/com/android/server/am/EventLogTags.logtags +++ b/services/java/com/android/server/am/EventLogTags.logtags @@ -83,3 +83,6 @@ option java_package com.android.server.am 30039 am_crash (User|1|5),(PID|1|5),(Process Name|3),(Flags|1|5),(Exception|3),(Message|3),(File|3),(Line|1|5) # Log.wtf() called 30040 am_wtf (User|1|5),(PID|1|5),(Process Name|3),(Flags|1|5),(Tag|3),(Message|3) + +# User switched +30041 am_switch_user (id|1|5) diff --git a/services/java/com/android/server/display/PersistentDataStore.java b/services/java/com/android/server/display/PersistentDataStore.java index 3a6e1a6..105c253 100644 --- a/services/java/com/android/server/display/PersistentDataStore.java +++ b/services/java/com/android/server/display/PersistentDataStore.java @@ -81,6 +81,15 @@ final class PersistentDataStore { } } + public WifiDisplay getRememberedWifiDisplay(String deviceAddress) { + loadIfNeeded(); + int index = findRememberedWifiDisplay(deviceAddress); + if (index >= 0) { + return mRememberedWifiDisplays.get(index); + } + return null; + } + public WifiDisplay[] getRememberedWifiDisplays() { loadIfNeeded(); return mRememberedWifiDisplays.toArray(new WifiDisplay[mRememberedWifiDisplays.size()]); @@ -137,22 +146,6 @@ final class PersistentDataStore { return true; } - public boolean renameWifiDisplay(String deviceAddress, String alias) { - int index = findRememberedWifiDisplay(deviceAddress); - if (index >= 0) { - WifiDisplay display = mRememberedWifiDisplays.get(index); - if (Objects.equal(display.getDeviceAlias(), alias)) { - return false; // already has this alias - } - WifiDisplay renamedDisplay = new WifiDisplay(deviceAddress, - display.getDeviceName(), alias); - mRememberedWifiDisplays.set(index, renamedDisplay); - setDirty(); - return true; - } - return false; - } - public boolean forgetWifiDisplay(String deviceAddress) { int index = findRememberedWifiDisplay(deviceAddress); if (index >= 0) { diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java index 45fff30..c8a44d2 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -45,6 +45,8 @@ import android.view.Surface; import java.io.PrintWriter; import java.util.Arrays; +import libcore.util.Objects; + /** * Connects to Wifi displays that implement the Miracast protocol. * <p> @@ -224,16 +226,18 @@ final class WifiDisplayAdapter extends DisplayAdapter { } } - if (mPersistentDataStore.renameWifiDisplay(address, alias)) { - mPersistentDataStore.saveIfNeeded(); - updateRememberedDisplaysLocked(); - scheduleStatusChangedBroadcastLocked(); + WifiDisplay display = mPersistentDataStore.getRememberedWifiDisplay(address); + if (display != null && !Objects.equal(display.getDeviceAlias(), alias)) { + display = new WifiDisplay(address, display.getDeviceName(), alias); + if (mPersistentDataStore.rememberWifiDisplay(display)) { + mPersistentDataStore.saveIfNeeded(); + updateRememberedDisplaysLocked(); + scheduleStatusChangedBroadcastLocked(); + } } - if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address) - && mDisplayDevice != null) { - mDisplayDevice.setNameLocked(mActiveDisplay.getFriendlyDisplayName()); - sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED); + if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address)) { + renameDisplayDeviceLocked(mActiveDisplay.getFriendlyDisplayName()); } } @@ -272,9 +276,42 @@ final class WifiDisplayAdapter extends DisplayAdapter { mAvailableDisplays = mPersistentDataStore.applyWifiDisplayAliases(mAvailableDisplays); } - private void handleConnectLocked(WifiDisplay display, + private void fixRememberedDisplayNamesFromAvailableDisplaysLocked() { + // It may happen that a display name has changed since it was remembered. + // Consult the list of available displays and update the name if needed. + // We don't do anything special for the active display here. The display + // controller will send a separate event when it needs to be updates. + boolean changed = false; + for (int i = 0; i < mRememberedDisplays.length; i++) { + WifiDisplay rememberedDisplay = mRememberedDisplays[i]; + WifiDisplay availableDisplay = findAvailableDisplayLocked( + rememberedDisplay.getDeviceAddress()); + if (availableDisplay != null && !rememberedDisplay.equals(availableDisplay)) { + if (DEBUG) { + Slog.d(TAG, "fixRememberedDisplayNamesFromAvailableDisplaysLocked: " + + "updating remembered display to " + availableDisplay); + } + mRememberedDisplays[i] = availableDisplay; + changed |= mPersistentDataStore.rememberWifiDisplay(availableDisplay); + } + } + if (changed) { + mPersistentDataStore.saveIfNeeded(); + } + } + + private WifiDisplay findAvailableDisplayLocked(String address) { + for (WifiDisplay display : mAvailableDisplays) { + if (display.getDeviceAddress().equals(address)) { + return display; + } + } + return null; + } + + private void addDisplayDeviceLocked(WifiDisplay display, Surface surface, int width, int height, int flags) { - handleDisconnectLocked(); + removeDisplayDeviceLocked(); if (mPersistentDataStore.rememberWifiDisplay(display)) { mPersistentDataStore.saveIfNeeded(); @@ -303,7 +340,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { scheduleUpdateNotificationLocked(); } - private void handleDisconnectLocked() { + private void removeDisplayDeviceLocked() { if (mDisplayDevice != null) { mDisplayDevice.clearSurfaceLocked(); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED); @@ -313,6 +350,13 @@ final class WifiDisplayAdapter extends DisplayAdapter { } } + private void renameDisplayDeviceLocked(String name) { + if (mDisplayDevice != null && !mDisplayDevice.getNameLocked().equals(name)) { + mDisplayDevice.setNameLocked(name); + sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED); + } + } + private void scheduleStatusChangedBroadcastLocked() { mCurrentStatus = null; if (!mPendingStatusChangeBroadcast) { @@ -446,6 +490,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { || !Arrays.equals(mAvailableDisplays, availableDisplays)) { mScanState = WifiDisplayStatus.SCAN_STATE_NOT_SCANNING; mAvailableDisplays = availableDisplays; + fixRememberedDisplayNamesFromAvailableDisplaysLocked(); scheduleStatusChangedBroadcastLocked(); } } @@ -483,7 +528,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { int width, int height, int flags) { synchronized (getSyncRoot()) { display = mPersistentDataStore.applyWifiDisplayAlias(display); - handleConnectLocked(display, surface, width, height, flags); + addDisplayDeviceLocked(display, surface, width, height, flags); if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED || mActiveDisplay == null @@ -496,10 +541,24 @@ final class WifiDisplayAdapter extends DisplayAdapter { } @Override + public void onDisplayChanged(WifiDisplay display) { + synchronized (getSyncRoot()) { + display = mPersistentDataStore.applyWifiDisplayAlias(display); + if (mActiveDisplay != null + && mActiveDisplay.hasSameAddress(display) + && !mActiveDisplay.equals(display)) { + mActiveDisplay = display; + renameDisplayDeviceLocked(display.getFriendlyDisplayName()); + scheduleStatusChangedBroadcastLocked(); + } + } + } + + @Override public void onDisplayDisconnected() { // Stop listening. synchronized (getSyncRoot()) { - handleDisconnectLocked(); + removeDisplayDeviceLocked(); if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED || mActiveDisplay != null) { diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java index 39d042f..886e049 100644 --- a/services/java/com/android/server/display/WifiDisplayController.java +++ b/services/java/com/android/server/display/WifiDisplayController.java @@ -120,6 +120,12 @@ final class WifiDisplayController implements DumpUtils.Dump { // or are not trying to connect. private WifiP2pDevice mConnectingDevice; + // The device from which we are currently disconnecting. + private WifiP2pDevice mDisconnectingDevice; + + // The device to which we were previously trying to connect and are now canceling. + private WifiP2pDevice mCancelingDevice; + // The device to which we are currently connected, which means we have an active P2P group. private WifiP2pDevice mConnectedDevice; @@ -186,6 +192,7 @@ final class WifiDisplayController implements DumpUtils.Dump { updateWfdEnableState(); } + @Override public void dump(PrintWriter pw) { pw.println("mWifiDisplayOnSetting=" + mWifiDisplayOnSetting); pw.println("mWifiP2pEnabled=" + mWifiP2pEnabled); @@ -196,6 +203,8 @@ final class WifiDisplayController implements DumpUtils.Dump { pw.println("mDiscoverPeersRetriesLeft=" + mDiscoverPeersRetriesLeft); pw.println("mDesiredDevice=" + describeWifiP2pDevice(mDesiredDevice)); pw.println("mConnectingDisplay=" + describeWifiP2pDevice(mConnectingDevice)); + pw.println("mDisconnectingDisplay=" + describeWifiP2pDevice(mDisconnectingDevice)); + pw.println("mCancelingDisplay=" + describeWifiP2pDevice(mCancelingDevice)); pw.println("mConnectedDevice=" + describeWifiP2pDevice(mConnectedDevice)); pw.println("mConnectionRetriesLeft=" + mConnectionRetriesLeft); pw.println("mRemoteDisplay=" + mRemoteDisplay); @@ -384,7 +393,9 @@ final class WifiDisplayController implements DumpUtils.Dump { final int count = mAvailableWifiDisplayPeers.size(); final WifiDisplay[] displays = WifiDisplay.CREATOR.newArray(count); for (int i = 0; i < count; i++) { - displays[i] = createWifiDisplay(mAvailableWifiDisplayPeers.get(i)); + WifiP2pDevice device = mAvailableWifiDisplayPeers.get(i); + displays[i] = createWifiDisplay(device); + updateDesiredDevice(device); } mHandler.post(new Runnable() { @@ -395,6 +406,23 @@ final class WifiDisplayController implements DumpUtils.Dump { }); } + private void updateDesiredDevice(WifiP2pDevice device) { + // Handle the case where the device to which we are connecting or connected + // may have been renamed or reported different properties in the latest scan. + final String address = device.deviceAddress; + if (mDesiredDevice != null && mDesiredDevice.deviceAddress.equals(address)) { + if (DEBUG) { + Slog.d(TAG, "updateDesiredDevice: new information " + + describeWifiP2pDevice(device)); + } + mDesiredDevice.update(device); + if (mAdvertisedDisplay != null + && mAdvertisedDisplay.getDeviceAddress().equals(address)) { + readvertiseDisplay(createWifiDisplay(mDesiredDevice)); + } + } + } + private void connect(final WifiP2pDevice device) { if (mDesiredDevice != null && !mDesiredDevice.deviceAddress.equals(device.deviceAddress)) { @@ -459,12 +487,17 @@ final class WifiDisplayController implements DumpUtils.Dump { } // Step 2. Before we try to connect to a new device, disconnect from the old one. + if (mDisconnectingDevice != null) { + return; // wait for asynchronous callback + } if (mConnectedDevice != null && mConnectedDevice != mDesiredDevice) { Slog.i(TAG, "Disconnecting from Wifi display: " + mConnectedDevice.deviceName); + mDisconnectingDevice = mConnectedDevice; + mConnectedDevice = null; unadvertiseDisplay(); - final WifiP2pDevice oldDevice = mConnectedDevice; + final WifiP2pDevice oldDevice = mDisconnectingDevice; mWifiP2pManager.removeGroup(mWifiP2pChannel, new ActionListener() { @Override public void onSuccess() { @@ -480,8 +513,8 @@ final class WifiDisplayController implements DumpUtils.Dump { } private void next() { - if (mConnectedDevice == oldDevice) { - mConnectedDevice = null; + if (mDisconnectingDevice == oldDevice) { + mDisconnectingDevice = null; updateConnection(); } } @@ -491,13 +524,18 @@ final class WifiDisplayController implements DumpUtils.Dump { // Step 3. Before we try to connect to a new device, stop trying to connect // to the old one. + if (mCancelingDevice != null) { + return; // wait for asynchronous callback + } if (mConnectingDevice != null && mConnectingDevice != mDesiredDevice) { Slog.i(TAG, "Canceling connection to Wifi display: " + mConnectingDevice.deviceName); + mCancelingDevice = mConnectingDevice; + mConnectingDevice = null; unadvertiseDisplay(); mHandler.removeCallbacks(mConnectionTimeout); - final WifiP2pDevice oldDevice = mConnectingDevice; + final WifiP2pDevice oldDevice = mCancelingDevice; mWifiP2pManager.cancelConnect(mWifiP2pChannel, new ActionListener() { @Override public void onSuccess() { @@ -513,8 +551,8 @@ final class WifiDisplayController implements DumpUtils.Dump { } private void next() { - if (mConnectingDevice == oldDevice) { - mConnectingDevice = null; + if (mCancelingDevice == oldDevice) { + mCancelingDevice = null; updateConnection(); } } @@ -763,13 +801,17 @@ final class WifiDisplayController implements DumpUtils.Dump { public void run() { if (oldSurface != null && surface != oldSurface) { mListener.onDisplayDisconnected(); - } else if (oldDisplay != null && !Objects.equal(display, oldDisplay)) { + } else if (oldDisplay != null && !oldDisplay.hasSameAddress(display)) { mListener.onDisplayConnectionFailed(); } if (display != null) { - if (!Objects.equal(display, oldDisplay)) { + if (!display.hasSameAddress(oldDisplay)) { mListener.onDisplayConnecting(display); + } else if (!display.equals(oldDisplay)) { + // The address is the same but some other property such as the + // name must have changed. + mListener.onDisplayChanged(display); } if (surface != null && surface != oldSurface) { mListener.onDisplayConnected(display, surface, width, height, flags); @@ -784,6 +826,12 @@ final class WifiDisplayController implements DumpUtils.Dump { advertiseDisplay(null, null, 0, 0, 0); } + private void readvertiseDisplay(WifiDisplay display) { + advertiseDisplay(display, mAdvertisedDisplaySurface, + mAdvertisedDisplayWidth, mAdvertisedDisplayHeight, + mAdvertisedDisplayFlags); + } + private static Inet4Address getInterfaceAddress(WifiP2pGroup info) { NetworkInterface iface; try { @@ -885,6 +933,7 @@ final class WifiDisplayController implements DumpUtils.Dump { void onDisplayConnecting(WifiDisplay display); void onDisplayConnectionFailed(); + void onDisplayChanged(WifiDisplay display); void onDisplayConnected(WifiDisplay display, Surface surface, int width, int height, int flags); void onDisplayDisconnected(); diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java index e05442b..66c3ce9 100644 --- a/services/java/com/android/server/pm/UserManagerService.java +++ b/services/java/com/android/server/pm/UserManagerService.java @@ -16,8 +16,7 @@ package com.android.server.pm; -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.FastXmlSerializer; +import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import android.app.Activity; import android.app.ActivityManager; @@ -26,7 +25,6 @@ import android.app.IStopUserCallback; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.graphics.Bitmap; @@ -34,6 +32,7 @@ import android.graphics.BitmapFactory; import android.os.Binder; import android.os.Environment; import android.os.FileUtils; +import android.os.Handler; import android.os.IUserManager; import android.os.Process; import android.os.RemoteException; @@ -42,9 +41,17 @@ import android.os.UserManager; import android.util.AtomicFile; import android.util.Slog; import android.util.SparseArray; +import android.util.SparseBooleanArray; import android.util.TimeUtils; import android.util.Xml; +import com.android.internal.util.ArrayUtils; +import com.android.internal.util.FastXmlSerializer; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + import java.io.BufferedOutputStream; import java.io.File; import java.io.FileDescriptor; @@ -54,13 +61,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - public class UserManagerService extends IUserManager.Stub { private static final String LOG_TAG = "UserManagerService"; @@ -95,19 +97,24 @@ public class UserManagerService extends IUserManager.Stub { private final Object mInstallLock; private final Object mPackagesLock; + private final Handler mHandler; + private final File mUsersDir; private final File mUserListFile; private final File mBaseUserPath; - private SparseArray<UserInfo> mUsers = new SparseArray<UserInfo>(); - private HashSet<Integer> mRemovingUserIds = new HashSet<Integer>(); + private final SparseArray<UserInfo> mUsers = new SparseArray<UserInfo>(); + + /** + * Set of user IDs being actively removed. Removed IDs linger in this set + * for several seconds to work around a VFS caching issue. + */ + // @GuardedBy("mPackagesLock") + private final SparseBooleanArray mRemovingUserIds = new SparseBooleanArray(); private int[] mUserIds; private boolean mGuestEnabled; private int mNextSerialNumber; - // This resets on a reboot. Otherwise it keeps incrementing so that user ids are - // not reused in quick succession - private int mNextUserId = MIN_USER_ID; private int mUserVersion = 0; private static UserManagerService sInstance; @@ -147,6 +154,7 @@ public class UserManagerService extends IUserManager.Stub { mPm = pm; mInstallLock = installLock; mPackagesLock = packagesLock; + mHandler = new Handler(); synchronized (mInstallLock) { synchronized (mPackagesLock) { mUsersDir = new File(dataDir, USER_INFO_DIR); @@ -190,7 +198,7 @@ public class UserManagerService extends IUserManager.Stub { if (ui.partial) { continue; } - if (!excludeDying || !mRemovingUserIds.contains(ui.id)) { + if (!excludeDying || !mRemovingUserIds.get(ui.id)) { users.add(ui); } } @@ -212,7 +220,7 @@ public class UserManagerService extends IUserManager.Stub { private UserInfo getUserInfoLocked(int userId) { UserInfo ui = mUsers.get(userId); // If it is partial and not in the process of being removed, return as unknown user. - if (ui != null && ui.partial && !mRemovingUserIds.contains(userId)) { + if (ui != null && ui.partial && !mRemovingUserIds.get(userId)) { Slog.w(LOG_TAG, "getUserInfo: unknown user #" + userId); return null; } @@ -502,7 +510,7 @@ public class UserManagerService extends IUserManager.Stub { private void fallbackToSingleUserLocked() { // Create the primary user - UserInfo primary = new UserInfo(0, + UserInfo primary = new UserInfo(0, mContext.getResources().getString(com.android.internal.R.string.owner_name), null, UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED); mUsers.put(0, primary); @@ -749,7 +757,7 @@ public class UserManagerService extends IUserManager.Stub { if (userHandle == 0 || user == null) { return false; } - mRemovingUserIds.add(userHandle); + mRemovingUserIds.put(userHandle, true); // Set this to a partially created user, so that the user will be purged // on next startup, in case the runtime stops now before stopping and // removing the user completely. @@ -813,13 +821,25 @@ public class UserManagerService extends IUserManager.Stub { } } - private void removeUserStateLocked(int userHandle) { + private void removeUserStateLocked(final int userHandle) { // Cleanup package manager settings mPm.cleanUpUserLILPw(userHandle); // Remove this user from the list mUsers.remove(userHandle); - mRemovingUserIds.remove(userHandle); + + // Have user ID linger for several seconds to let external storage VFS + // cache entries expire. This must be greater than the 'entry_valid' + // timeout used by the FUSE daemon. + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + synchronized (mPackagesLock) { + mRemovingUserIds.delete(userHandle); + } + } + }, MINUTE_IN_MILLIS); + // Remove user file AtomicFile userFile = new AtomicFile(new File(mUsersDir, userHandle + ".xml")); userFile.delete(); @@ -906,14 +926,13 @@ public class UserManagerService extends IUserManager.Stub { */ private int getNextAvailableIdLocked() { synchronized (mPackagesLock) { - int i = mNextUserId; + int i = MIN_USER_ID; while (i < Integer.MAX_VALUE) { - if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.contains(i)) { + if (mUsers.indexOfKey(i) < 0 && !mRemovingUserIds.get(i)) { break; } i++; } - mNextUserId = i + 1; return i; } } @@ -938,7 +957,7 @@ public class UserManagerService extends IUserManager.Stub { UserInfo user = mUsers.valueAt(i); if (user == null) continue; pw.print(" "); pw.print(user); pw.print(" serialNo="); pw.print(user.serialNumber); - if (mRemovingUserIds.contains(mUsers.keyAt(i))) pw.print(" <removing> "); + if (mRemovingUserIds.get(mUsers.keyAt(i))) pw.print(" <removing> "); if (user.partial) pw.print(" <partial>"); pw.println(); pw.print(" Created: "); |
