am 625c1083: Merge "docs: Support Library r11 Release Notes" into jb-mr1-dev
* commit '625c108329ad4ae29d0699543fee9b587dfb87fa':
docs: Support Library r11 Release Notes
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 43a163d..6382cee 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -858,6 +858,9 @@
*/
public Intent getAssistIntent(Context context, int userHandle) {
try {
+ if (mService == null) {
+ return null;
+ }
ComponentName comp = mService.getAssistIntent(userHandle);
if (comp == null) {
return null;
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index f07002e..6f1cc94 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -930,11 +930,13 @@
*/
public void onConfigureWindow(Window win, boolean isFullscreen,
boolean isCandidatesOnly) {
- if (isFullscreen) {
- mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);
- } else {
- mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
+ final int currentHeight = mWindow.getWindow().getAttributes().height;
+ final int newHeight = isFullscreen ? MATCH_PARENT : WRAP_CONTENT;
+ if (mIsInputViewShown && currentHeight != newHeight) {
+ Log.w(TAG, "Window size has been changed. This may cause jankiness of resizing window: "
+ + currentHeight + " -> " + newHeight);
}
+ mWindow.getWindow().setLayout(MATCH_PARENT, newHeight);
}
/**
@@ -997,10 +999,11 @@
}
void updateExtractFrameVisibility() {
- int vis;
+ final int vis;
if (isFullscreenMode()) {
vis = mExtractViewHidden ? View.INVISIBLE : View.VISIBLE;
- mExtractFrame.setVisibility(View.VISIBLE);
+ // "vis" should be applied for the extract frame as well in the fullscreen mode.
+ mExtractFrame.setVisibility(vis);
} else {
vis = View.VISIBLE;
mExtractFrame.setVisibility(View.GONE);
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 874e80a..8dc900e 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -351,6 +351,8 @@
DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
if (dhcpAction == DhcpAction.START) {
+ /* Stop any existing DHCP daemon before starting new */
+ NetworkUtils.stopDhcp(mInterfaceName);
if (DBG) Log.d(TAG, "DHCP request on " + mInterfaceName);
success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
mDhcpInfo = dhcpInfoInternal;
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index ed51818..0ca9183 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -44,6 +44,7 @@
public static final long TRACE_TAG_AUDIO = 1L << 8;
public static final long TRACE_TAG_VIDEO = 1L << 9;
public static final long TRACE_TAG_CAMERA = 1L << 10;
+ private static final long TRACE_TAG_NOT_READY = 1L << 63;
public static final int TRACE_FLAGS_START_BIT = 1;
public static final String[] TRACE_TAGS = {
@@ -53,11 +54,8 @@
public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
- // This works as a "not ready" flag because TRACE_TAG_ALWAYS is always set.
- private static final long TRACE_FLAGS_NOT_READY = 0;
-
// Must be volatile to avoid word tearing.
- private static volatile long sEnabledTags = TRACE_FLAGS_NOT_READY;
+ private static volatile long sEnabledTags = TRACE_TAG_NOT_READY;
private static native long nativeGetEnabledTags();
private static native void nativeTraceCounter(long tag, String name, int value);
@@ -99,7 +97,7 @@
*/
private static long cacheEnabledTags() {
long tags = nativeGetEnabledTags();
- if (tags == TRACE_FLAGS_NOT_READY) {
+ if (tags == TRACE_TAG_NOT_READY) {
Log.w(TAG, "Unexpected value from nativeGetEnabledTags: " + tags);
// keep going
}
@@ -115,7 +113,7 @@
*/
public static boolean isTagEnabled(long traceTag) {
long tags = sEnabledTags;
- if (tags == TRACE_FLAGS_NOT_READY) {
+ if (tags == TRACE_TAG_NOT_READY) {
tags = cacheEnabledTags();
}
return (tags & traceTag) != 0;
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index e7c4c23..9537ac4 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -122,9 +122,9 @@
return (jboolean)(::wifi_start_supplicant(p2pSupported) == 0);
}
-static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject)
+static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
{
- return (jboolean)(::wifi_stop_supplicant() == 0);
+ return (jboolean)(::wifi_stop_supplicant(p2pSupported) == 0);
}
static jboolean android_net_wifi_connectToSupplicant(JNIEnv* env, jobject, jstring jIface)
@@ -204,7 +204,7 @@
{ "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded },
{ "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver },
{ "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant },
- { "killSupplicant", "()Z", (void *)android_net_wifi_killSupplicant },
+ { "killSupplicant", "(Z)Z", (void *)android_net_wifi_killSupplicant },
{ "connectToSupplicant", "(Ljava/lang/String;)Z",
(void *)android_net_wifi_connectToSupplicant },
{ "closeSupplicantConnection", "(Ljava/lang/String;)V",
diff --git a/core/res/res/drawable-hdpi/ic_coins_l.png b/core/res/res/drawable-hdpi/ic_coins_l.png
new file mode 100644
index 0000000..e1e3e2a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_coins_l.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_coins_l.png b/core/res/res/drawable-mdpi/ic_coins_l.png
new file mode 100644
index 0000000..a6d7abb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_coins_l.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_coins_l.png b/core/res/res/drawable-xhdpi/ic_coins_l.png
new file mode 100644
index 0000000..84e7e72
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_coins_l.png
Binary files differ
diff --git a/core/res/res/layout/sms_short_code_confirmation_dialog.xml b/core/res/res/layout/sms_short_code_confirmation_dialog.xml
index ec39d97..d82f560 100644
--- a/core/res/res/layout/sms_short_code_confirmation_dialog.xml
+++ b/core/res/res/layout/sms_short_code_confirmation_dialog.xml
@@ -30,9 +30,9 @@
style="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="16dip"
- android:paddingRight="16dip"
- android:paddingTop="8dip"
+ android:paddingLeft="20dip"
+ android:paddingRight="20dip"
+ android:paddingTop="16dip"
android:paddingBottom="16dip" />
<TableLayout android:id="@+id/sms_short_code_detail_layout"
@@ -51,7 +51,7 @@
android:layout_height="wrap_content"
android:paddingLeft="8dip"
android:paddingRight="8dip"
- android:src="@null" />
+ android:src="@drawable/ic_coins_l" />
<TextView android:id="@+id/sms_short_code_detail_message"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
@@ -60,14 +60,19 @@
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
-
- <CheckBox android:id="@+id/sms_short_code_remember_choice_checkbox"
- android:layout_width="wrap_content"
+ <RelativeLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingRight="8dip" />
+ android:paddingTop="12dip"
+ android:paddingLeft="8dip" >
+ <CheckBox android:id="@+id/sms_short_code_remember_choice_checkbox"
+ android:paddingTop="11dip"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ </RelativeLayout>
<TextView android:id="@+id/sms_short_code_remember_choice_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:paddingTop="18dip"
android:text="@string/sms_short_code_remember_choice" />
</TableRow>
@@ -77,6 +82,7 @@
<Space android:layout_gravity="fill" />
<TextView android:id="@+id/sms_short_code_remember_undo_instruction"
+ android:paddingTop="10dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 315196e..22f699f 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -436,6 +436,8 @@
private boolean mDockAudioMediaEnabled = true;
+ private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+
///////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////
@@ -3324,6 +3326,13 @@
mBluetoothA2dpEnabled ?
AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP);
}
+
+ synchronized (mSettingsLock) {
+ AudioSystem.setForceUse(AudioSystem.FOR_DOCK,
+ mDockAudioMediaEnabled ?
+ AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE);
+ }
+
// indicate the end of reconfiguration phase to audio HAL
AudioSystem.setParameters("restarting=false");
break;
@@ -3751,13 +3760,7 @@
config = AudioSystem.FORCE_BT_CAR_DOCK;
break;
case Intent.EXTRA_DOCK_STATE_LE_DESK:
- synchronized (mSettingsLock) {
- if (mDockAudioMediaEnabled) {
- config = AudioSystem.FORCE_ANALOG_DOCK;
- } else {
- config = AudioSystem.FORCE_NONE;
- }
- }
+ config = AudioSystem.FORCE_ANALOG_DOCK;
break;
case Intent.EXTRA_DOCK_STATE_HE_DESK:
config = AudioSystem.FORCE_DIGITAL_DOCK;
@@ -3766,8 +3769,14 @@
default:
config = AudioSystem.FORCE_NONE;
}
-
- AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
+ // Low end docks have a menu to enable or disable audio
+ // (see mDockAudioMediaEnabled)
+ if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) ||
+ ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) &&
+ (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) {
+ AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
+ }
+ mDockState = dockState;
} else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
BluetoothProfile.STATE_DISCONNECTED);
diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
index 2669c7e..b1104cc 100644
--- a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
@@ -141,7 +141,7 @@
/>
</LinearLayout>
- <ImageView
+ <com.android.systemui.statusbar.policy.KeyButtonView
android:layout_width="128dp"
android:id="@+id/search_light"
android:layout_height="match_parent"
@@ -282,7 +282,7 @@
/>
</LinearLayout>
- <ImageView
+ <com.android.systemui.statusbar.policy.KeyButtonView
android:layout_width="162dp"
android:id="@+id/search_light"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 440a4e1..da52d89 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -145,7 +145,7 @@
/>
</LinearLayout>
- <ImageView
+ <com.android.systemui.statusbar.policy.KeyButtonView
android:layout_width="80dp"
android:id="@+id/search_light"
android:layout_height="match_parent"
@@ -289,7 +289,7 @@
/>
</LinearLayout>
- <ImageView
+ <com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/search_light"
android:layout_height="80dp"
android:layout_width="match_parent"
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index df4c661..c227619 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -22,6 +22,7 @@
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.PendingIntent;
+import android.app.SearchManager;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -166,6 +167,9 @@
/** UserManager for querying number of users */
private UserManager mUserManager;
+ /** SearchManager for determining whether or not search assistant is available */
+ private SearchManager mSearchManager;
+
/**
* Used to keep the device awake while to ensure the keyguard finishes opening before
* we sleep.
@@ -527,6 +531,7 @@
* Let us know that the system is ready after startup.
*/
public void onSystemReady() {
+ mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
synchronized (this) {
if (DEBUG) Log.d(TAG, "onSystemReady");
mSystemReady = true;
@@ -1313,6 +1318,9 @@
// showing secure lockscreen; disable ticker.
flags |= StatusBarManager.DISABLE_NOTIFICATION_TICKER;
}
+ if (!isAssistantAvailable()) {
+ flags |= StatusBarManager.DISABLE_SEARCH;
+ }
}
if (DEBUG) {
@@ -1410,4 +1418,8 @@
mKeyguardViewManager.showAssistant();
}
+ private boolean isAssistantAvailable() {
+ return mSearchManager != null
+ && mSearchManager.getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
+ }
}
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 @@
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 @@
# ---------------------------
# 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 @@
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 @@
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/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.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.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.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.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 @@
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 @@
mPm = pm;
mInstallLock = installLock;
mPackagesLock = packagesLock;
+ mHandler = new Handler();
synchronized (mInstallLock) {
synchronized (mPackagesLock) {
mUsersDir = new File(dataDir, USER_INFO_DIR);
@@ -190,7 +198,7 @@
if (ui.partial) {
continue;
}
- if (!excludeDying || !mRemovingUserIds.contains(ui.id)) {
+ if (!excludeDying || !mRemovingUserIds.get(ui.id)) {
users.add(ui);
}
}
@@ -212,7 +220,7 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
*/
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 @@
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: ");
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index b871cdc..0e29882 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -508,6 +508,10 @@
private Messenger mWifiServiceMessenger;
private final CountDownLatch mConnected = new CountDownLatch(1);
+ private static Object sThreadRefLock = new Object();
+ private static int sThreadRefCount;
+ private static HandlerThread sHandlerThread;
+
/**
* Create a new WifiManager instance.
* Applications will almost always want to use
@@ -1365,9 +1369,14 @@
return;
}
- HandlerThread t = new HandlerThread("WifiManager");
- t.start();
- mHandler = new ServiceHandler(t.getLooper());
+ synchronized (sThreadRefLock) {
+ if (++sThreadRefCount == 1) {
+ sHandlerThread = new HandlerThread("WifiManager");
+ sHandlerThread.start();
+ }
+ }
+
+ mHandler = new ServiceHandler(sHandlerThread.getLooper());
mAsyncChannel.connect(mContext, mHandler, mWifiServiceMessenger);
try {
mConnected.await();
@@ -1983,8 +1992,10 @@
protected void finalize() throws Throwable {
try {
- if (mHandler != null && mHandler.getLooper() != null) {
- mHandler.getLooper().quit();
+ synchronized (sThreadRefLock) {
+ if (--sThreadRefCount == 0 && sHandlerThread != null) {
+ sHandlerThread.getLooper().quit();
+ }
}
} finally {
super.finalize();
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 4c5fc5d..5e25623 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -61,7 +61,7 @@
/* Sends a kill signal to supplicant. To be used when we have lost connection
or when the supplicant is hung */
- public native static boolean killSupplicant();
+ public native static boolean killSupplicant(boolean p2pSupported);
private native boolean connectToSupplicant(String iface);
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 040ff24..dafa8e8 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1944,6 +1944,7 @@
case CMD_STOP_DRIVER:
case CMD_DELAYED_STOP_DRIVER:
case CMD_DRIVER_START_TIMED_OUT:
+ case CMD_CAPTIVE_CHECK_COMPLETE:
case CMD_START_AP:
case CMD_START_AP_SUCCESS:
case CMD_START_AP_FAILURE:
@@ -2189,6 +2190,13 @@
loge("Unable to change interface settings: " + ie);
}
+ /* Stop a running supplicant after a runtime restart
+ * Avoids issues with drivers that do not handle interface down
+ * on a running supplicant properly.
+ */
+ if (DBG) log("Kill any running supplicant");
+ mWifiNative.killSupplicant(mP2pSupported);
+
if(mWifiNative.startSupplicant(mP2pSupported)) {
if (DBG) log("Supplicant start successful");
mWifiMonitor.startMonitoring();
@@ -2384,7 +2392,7 @@
case WifiMonitor.SUP_DISCONNECTION_EVENT:
if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
loge("Failed to setup control channel, restart supplicant");
- mWifiNative.killSupplicant();
+ mWifiNative.killSupplicant(mP2pSupported);
transitionTo(mDriverLoadedState);
sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
} else {
@@ -2451,7 +2459,7 @@
break;
case WifiMonitor.SUP_DISCONNECTION_EVENT: /* Supplicant connection lost */
loge("Connection lost, restart supplicant");
- mWifiNative.killSupplicant();
+ mWifiNative.killSupplicant(mP2pSupported);
mWifiNative.closeSupplicantConnection();
mNetworkInfo.setIsAvailable(false);
handleNetworkDisconnect();
@@ -2605,14 +2613,14 @@
/* Socket connection can be lost when we do a graceful shutdown
* or when the driver is hung. Ensure supplicant is stopped here.
*/
- mWifiNative.killSupplicant();
+ mWifiNative.killSupplicant(mP2pSupported);
mWifiNative.closeSupplicantConnection();
transitionTo(mDriverLoadedState);
break;
case CMD_STOP_SUPPLICANT_FAILED:
if (message.arg1 == mSupplicantStopFailureToken) {
loge("Timed out on a supplicant stop, kill and proceed");
- mWifiNative.killSupplicant();
+ mWifiNative.killSupplicant(mP2pSupported);
mWifiNative.closeSupplicantConnection();
transitionTo(mDriverLoadedState);
}