Merge "Clean up activities and displays when done" into klp-modular-dev
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
index a7d287b..461e8b8 100644
--- a/core/java/android/net/ProxyDataTracker.java
+++ b/core/java/android/net/ProxyDataTracker.java
@@ -16,13 +16,24 @@
package android.net;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -31,27 +42,70 @@
* {@hide}
*/
public class ProxyDataTracker extends BaseNetworkStateTracker {
- private static final String NETWORK_TYPE = "PROXY";
private static final String TAG = "ProxyDataTracker";
+ private static final String NETWORK_TYPE = "PROXY";
// TODO: investigate how to get these DNS addresses from the system.
private static final String DNS1 = "8.8.8.8";
private static final String DNS2 = "8.8.4.4";
private static final String REASON_ENABLED = "enabled";
+ private static final String REASON_DISABLED = "disabled";
+ private static final String REASON_PROXY_DOWN = "proxy_down";
+ private static final int MSG_TEAR_DOWN_REQUEST = 1;
+ private static final int MSG_SETUP_REQUEST = 2;
+
+ private static final String PERMISSION_PROXY_STATUS_SENDER =
+ "android.permission.ACCESS_NETWORK_CONDITIONS";
+ private static final String ACTION_PROXY_STATUS_CHANGE =
+ "com.android.net.PROXY_STATUS_CHANGE";
+ private static final String KEY_IS_PROXY_AVAILABLE = "is_proxy_available";
+ private static final String KEY_REPLY_TO_MESSENGER_BINDER = "reply_to_messenger_binder";
+ private static final String KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE =
+ "reply_to_messenger_binder_bundle";
+
+ private Handler mTarget;
+ private Messenger mProxyStatusService;
+ private AtomicBoolean mReconnectRequested = new AtomicBoolean(false);
+ private AtomicBoolean mIsProxyAvailable = new AtomicBoolean(false);
private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
- private final AtomicInteger mReconnectGeneration = new AtomicInteger(0);
+
+ private final BroadcastReceiver mProxyStatusServiceListener = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(ACTION_PROXY_STATUS_CHANGE)) {
+ mIsProxyAvailable.set(intent.getBooleanExtra(KEY_IS_PROXY_AVAILABLE, false));
+ if (mIsProxyAvailable.get()) {
+ Bundle bundle = intent.getBundleExtra(KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE);
+ if (bundle == null || bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER) == null) {
+ Log.e(TAG, "no messenger binder in the intent to send future requests");
+ mIsProxyAvailable.set(false);
+ return;
+ }
+ mProxyStatusService =
+ new Messenger(bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER));
+ // If there is a pending reconnect request, do it now.
+ if (mReconnectRequested.get()) {
+ reconnect();
+ }
+ } else {
+ setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
+ REASON_PROXY_DOWN, null);
+ }
+ } else {
+ Log.d(TAG, "Unrecognized broadcast intent");
+ }
+ }
+ };
/**
* Create a new ProxyDataTracker
*/
public ProxyDataTracker() {
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, "");
- // TODO: update available state according to proxy state.
- mNetworkInfo.setIsAvailable(true);
mLinkProperties = new LinkProperties();
mLinkCapabilities = new LinkCapabilities();
-
+ mNetworkInfo.setIsAvailable(true);
try {
mLinkProperties.addDns(InetAddress.getByName(DNS1));
mLinkProperties.addDns(InetAddress.getByName(DNS2));
@@ -64,11 +118,31 @@
throw new CloneNotSupportedException();
}
+ @Override
+ public void startMonitoring(Context context, Handler target) {
+ mContext = context;
+ mTarget = target;
+ mContext.registerReceiver(mProxyStatusServiceListener,
+ new IntentFilter(ACTION_PROXY_STATUS_CHANGE),
+ PERMISSION_PROXY_STATUS_SENDER,
+ null);
+ }
+
/**
* Disable connectivity to the network.
*/
public boolean teardown() {
- // TODO: tell relevant service to tear down proxy.
+ setTeardownRequested(true);
+ mReconnectRequested.set(false);
+ try {
+ if (mIsProxyAvailable.get() && mProxyStatusService != null) {
+ mProxyStatusService.send(Message.obtain(null, MSG_TEAR_DOWN_REQUEST));
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to connect to proxy status service", e);
+ return false;
+ }
+ setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_DISABLED, null);
return true;
}
@@ -76,16 +150,24 @@
* Re-enable proxy data connectivity after a {@link #teardown()}.
*/
public boolean reconnect() {
- if (!isAvailable()) {
- Log.w(TAG, "Reconnect requested even though network is disabled. Bailing.");
+ mReconnectRequested.set(true);
+ setTeardownRequested(false);
+ if (!mIsProxyAvailable.get()) {
+ Log.w(TAG, "Reconnect requested even though proxy service is not up. Bailing.");
return false;
}
- setTeardownRequested(false);
- mReconnectGeneration.incrementAndGet();
- // TODO: tell relevant service to setup proxy. Set state to connected only if setup
- // succeeds.
- setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
+ setDetailedState(NetworkInfo.DetailedState.CONNECTING, REASON_ENABLED, null);
+ try {
+ mProxyStatusService.send(Message.obtain(null, MSG_SETUP_REQUEST));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to connect to proxy status service", e);
+ setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_PROXY_DOWN, null);
+ return false;
+ }
+ // We'll assume proxy is set up successfully. If not, a status change broadcast will be
+ // received afterwards to indicate any failure.
+ setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
return true;
}
@@ -116,7 +198,7 @@
private void setDetailedState(NetworkInfo.DetailedState state, String reason,
String extraInfo) {
mNetworkInfo.setDetailedState(state, reason, extraInfo);
- Message msg = getTargetHandler().obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
+ Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
msg.sendToTarget();
}
}
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 1fe4b08..5b0a4b2 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -630,7 +630,7 @@
if (producer == NULL)
goto not_valid_surface;
- window = new android::Surface(producer);
+ window = new android::Surface(producer, true);
if (window == NULL)
goto not_valid_surface;
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 559b11b..96a920d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1077,8 +1077,16 @@
<!-- Name of the wimax state tracker clas -->
<string name="config_wimaxStateTrackerClassname" translatable="false"></string>
- <!-- Is the dreams feature supported? -->
+ <!-- Specifies whether the dreams feature should be supported.
+ When true, the system will allow the user to configure dreams (screensavers)
+ to launch when a user activity timeout occurs or the system is told to nap.
+ When false, the dreams feature will be disabled (this does not affect dozing).
+
+ Consider setting this resource to false or disabling dreams by default when a
+ doze component is specified below since dreaming will supercede dozing and
+ will prevent the system from entering a low power state until the dream ends. -->
<bool name="config_dreamsSupported">true</bool>
+
<!-- If supported, are dreams enabled? (by default) -->
<bool name="config_dreamsEnabledByDefault">true</bool>
<!-- If supported and enabled, are dreams activated when docked? (by default) -->
diff --git a/docs/html/tools/help/avd-manager.jd b/docs/html/tools/help/avd-manager.jd
index ed90f43..20f6253 100644
--- a/docs/html/tools/help/avd-manager.jd
+++ b/docs/html/tools/help/avd-manager.jd
@@ -8,8 +8,11 @@
<p>You can launch the AVD Manager in one of the following ways:</p>
<ul>
- <li>In Eclipse: select <strong>Window > AVD Manager</strong>, or click
- the AVD Manager icon in the Eclipse toolbar.</li>
+ <li>In Eclipse: select <strong>Window > Android Virtual Device Manager</strong>, or click
+ the AVD Manager icon in the toolbar.</li>
+
+ <li>In Android Studio: select <strong>Tools > Android > AVD Manager</strong>, or click
+ the AVD Manager icon in the toolbar.</li>
<li>In other IDEs: Navigate to your SDK's <code>tools/</code> directory and execute
<code>android avd</code>.</li>
diff --git a/docs/html/tools/help/sdk-manager.jd b/docs/html/tools/help/sdk-manager.jd
index 276206f..57271bb 100644
--- a/docs/html/tools/help/sdk-manager.jd
+++ b/docs/html/tools/help/sdk-manager.jd
@@ -9,6 +9,8 @@
<ul>
<li>From Eclipse (with <a href="{@docRoot}tools/help/adt.html">ADT</a>),
select <strong>Window</strong> > <strong>Android SDK Manager</strong>.</li>
+ <li>From Android Studio, select <strong>Tools</strong> > <strong>Android</strong>
+ > <strong>SDK Manager</strong>.</li>
<li>On Windows, double-click the <code>SDK Manager.exe</code> file at the root of the Android
SDK directory.</li>
<li>On Mac or Linux, open a terminal and navigate to the <code>tools/</code> directory in the
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 76f29cd..e38db58 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1672,7 +1672,8 @@
return view.getParent() != null ? view : null;
} catch (WindowManager.BadTokenException e) {
// ignore
- Log.w(TAG, appToken + " already running, starting window not displayed");
+ Log.w(TAG, appToken + " already running, starting window not displayed. " +
+ e.getMessage());
} catch (RuntimeException e) {
// don't crash if something else bad happens, for example a
// failure loading resources because we are loading from an app
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 16b09bc..9ffcc8c 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1553,7 +1553,7 @@
return false;
}
if (!isBeingKeptAwakeLocked()) {
- if (!mIsPowered && !mDreamsEnabledByDefaultConfig) {
+ if (!mIsPowered && !mDreamsEnabledOnBatteryConfig) {
return false;
}
if (!mIsPowered
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 036804c..09c4e20 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -16,11 +16,12 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowManagerService.TAG;
+
import android.util.EventLog;
-import com.android.server.EventLogTags;
+import android.util.Slog;
class Task {
-// private final String TAG = "TaskGroup";
TaskStack mStack;
final AppTokenList mAppTokens = new AppTokenList();
final int taskId;
@@ -39,17 +40,24 @@
}
void addAppToken(int addPos, AppWindowToken wtoken) {
+ final int lastPos = mAppTokens.size();
+ if (addPos > lastPos) {
+ // We lost an app token. Don't crash though.
+ Slog.e(TAG, "Task.addAppToken: Out of bounds attempt token=" + wtoken + " addPos="
+ + addPos + " lastPos=" + lastPos);
+ addPos = lastPos;
+ }
mAppTokens.add(addPos, wtoken);
+ mDeferRemoval = false;
}
boolean removeAppToken(AppWindowToken wtoken) {
- mAppTokens.remove(wtoken);
+ boolean removed = mAppTokens.remove(wtoken);
if (mAppTokens.size() == 0) {
EventLog.writeEvent(com.android.server.EventLogTags.WM_TASK_REMOVED, taskId,
"removeAppToken: last token");
- return true;
}
- return false;
+ return removed;
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9655de0..fb5d7a7 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3487,7 +3487,7 @@
Task task = mTaskIdToTask.get(taskId);
if (task == null) {
- task = createTask(taskId, stackId, userId, atoken);
+ createTask(taskId, stackId, userId, atoken);
} else {
task.addAppToken(addPos, atoken);
}
@@ -3840,27 +3840,23 @@
}
synchronized(mWindowMap) {
- boolean changed = false;
+ final AppWindowToken newFocus;
if (token == null) {
if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
- changed = mFocusedApp != null;
- mFocusedApp = null;
- if (changed) {
- mInputMonitor.setFocusedAppLw(null);
- }
+ newFocus = null;
} else {
- AppWindowToken newFocus = findAppWindowToken(token);
+ newFocus = findAppWindowToken(token);
if (newFocus == null) {
Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
- return;
}
- changed = mFocusedApp != newFocus;
if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus
+ " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
+ }
+
+ final boolean changed = mFocusedApp != newFocus;
+ if (changed) {
mFocusedApp = newFocus;
- if (changed) {
- mInputMonitor.setFocusedAppLw(newFocus);
- }
+ mInputMonitor.setFocusedAppLw(null);
}
if (moveFocusNow && changed) {
@@ -4544,11 +4540,9 @@
void removeAppFromTaskLocked(AppWindowToken wtoken) {
final Task task = mTaskIdToTask.get(wtoken.groupId);
if (task != null) {
- task.removeAppToken(wtoken);
- // Remove after bug resolved.
- Slog.d(TAG, "removeAppFromTaskLocked: wtoken=" + wtoken
- + " numTokens left=" + task.mAppTokens.size()
- + " Callers=" + Debug.getCallers(5));
+ if (!task.removeAppToken(wtoken)) {
+ Slog.e(TAG, "removeAppFromTaskLocked: token=" + wtoken + " not found.");
+ }
}
}
@@ -4584,6 +4578,8 @@
TAG, "Removing app " + wtoken + " delayed=" + delayed
+ " animation=" + wtoken.mAppAnimator.animation
+ " animating=" + wtoken.mAppAnimator.animating);
+ if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "removeAppToken: "
+ + wtoken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
final TaskStack stack = mTaskIdToTask.get(wtoken.groupId).mStack;
if (delayed) {
// set the token aside because it has an active animation to be finished
@@ -4599,9 +4595,6 @@
wtoken.mAppAnimator.animating = false;
removeAppFromTaskLocked(wtoken);
}
- if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
- "removeAppToken: " + wtoken);
-
wtoken.removed = true;
if (wtoken.startingData != null) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0e056eb..db40cbe 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -857,9 +857,8 @@
}
}
- if (!disableNonCoreServices
- && context.getResources().getBoolean(R.bool.config_dreamsSupported)) {
- // Dreams (interactive idle-time views, a/k/a screen savers)
+ if (!disableNonCoreServices) {
+ // Dreams (interactive idle-time views, a/k/a screen savers, and doze mode)
mSystemServiceManager.startService(DreamManagerService.class);
}
@@ -1000,138 +999,131 @@
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
- final Handler handler = new Handler();
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
- // We initiate all boot phases on the SystemServer thread.
- handler.post(new Runnable() {
- @Override
- public void run() {
- Slog.i(TAG, "Making services ready");
- mSystemServiceManager.startBootPhase(
- SystemService.PHASE_ACTIVITY_MANAGER_READY);
+ Slog.i(TAG, "Making services ready");
+ mSystemServiceManager.startBootPhase(
+ SystemService.PHASE_ACTIVITY_MANAGER_READY);
- try {
- mActivityManagerService.startObservingNativeCrashes();
- } catch (Throwable e) {
- reportWtf("observing native crashes", e);
- }
- try {
- startSystemUi(context);
- } catch (Throwable e) {
- reportWtf("starting System UI", e);
- }
- try {
- if (mountServiceF != null) mountServiceF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Mount Service ready", e);
- }
- try {
- if (batteryF != null) batteryF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Battery Service ready", e);
- }
- try {
- if (networkManagementF != null) networkManagementF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Network Managment Service ready", e);
- }
- try {
- if (networkStatsF != null) networkStatsF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Network Stats Service ready", e);
- }
- try {
- if (networkPolicyF != null) networkPolicyF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Network Policy Service ready", e);
- }
- try {
- if (connectivityF != null) connectivityF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Connectivity Service ready", e);
- }
- try {
- if (dockF != null) dockF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Dock Service ready", e);
- }
- try {
- if (recognitionF != null) recognitionF.systemReady();
- } catch (Throwable e) {
- reportWtf("making Recognition Service ready", e);
- }
- Watchdog.getInstance().start();
+ try {
+ mActivityManagerService.startObservingNativeCrashes();
+ } catch (Throwable e) {
+ reportWtf("observing native crashes", e);
+ }
+ try {
+ startSystemUi(context);
+ } catch (Throwable e) {
+ reportWtf("starting System UI", e);
+ }
+ try {
+ if (mountServiceF != null) mountServiceF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Mount Service ready", e);
+ }
+ try {
+ if (batteryF != null) batteryF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Battery Service ready", e);
+ }
+ try {
+ if (networkManagementF != null) networkManagementF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Network Managment Service ready", e);
+ }
+ try {
+ if (networkStatsF != null) networkStatsF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Network Stats Service ready", e);
+ }
+ try {
+ if (networkPolicyF != null) networkPolicyF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Network Policy Service ready", e);
+ }
+ try {
+ if (connectivityF != null) connectivityF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Connectivity Service ready", e);
+ }
+ try {
+ if (dockF != null) dockF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Dock Service ready", e);
+ }
+ try {
+ if (recognitionF != null) recognitionF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Recognition Service ready", e);
+ }
+ Watchdog.getInstance().start();
- // It is now okay to let the various system services start their
- // third party code...
- mSystemServiceManager.startBootPhase(
- SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
+ // It is now okay to let the various system services start their
+ // third party code...
+ mSystemServiceManager.startBootPhase(
+ SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
- try {
- if (wallpaperF != null) wallpaperF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying WallpaperService running", e);
- }
- try {
- if (immF != null) immF.systemRunning(statusBarF);
- } catch (Throwable e) {
- reportWtf("Notifying InputMethodService running", e);
- }
- try {
- if (locationF != null) locationF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying Location Service running", e);
- }
- try {
- if (countryDetectorF != null) countryDetectorF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying CountryDetectorService running", e);
- }
- try {
- if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying NetworkTimeService running", e);
- }
- try {
- if (commonTimeMgmtServiceF != null) {
- commonTimeMgmtServiceF.systemRunning();
- }
- } catch (Throwable e) {
- reportWtf("Notifying CommonTimeManagementService running", e);
- }
- try {
- if (textServiceManagerServiceF != null)
- textServiceManagerServiceF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying TextServicesManagerService running", e);
- }
- try {
- if (atlasF != null) atlasF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying AssetAtlasService running", e);
- }
- try {
- // TODO(BT) Pass parameter to input manager
- if (inputManagerF != null) inputManagerF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying InputManagerService running", e);
- }
- try {
- if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying TelephonyRegistry running", e);
- }
- try {
- if (mediaRouterF != null) mediaRouterF.systemRunning();
- } catch (Throwable e) {
- reportWtf("Notifying MediaRouterService running", e);
- }
-
- mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETE);
+ try {
+ if (wallpaperF != null) wallpaperF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying WallpaperService running", e);
+ }
+ try {
+ if (immF != null) immF.systemRunning(statusBarF);
+ } catch (Throwable e) {
+ reportWtf("Notifying InputMethodService running", e);
+ }
+ try {
+ if (locationF != null) locationF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying Location Service running", e);
+ }
+ try {
+ if (countryDetectorF != null) countryDetectorF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying CountryDetectorService running", e);
+ }
+ try {
+ if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying NetworkTimeService running", e);
+ }
+ try {
+ if (commonTimeMgmtServiceF != null) {
+ commonTimeMgmtServiceF.systemRunning();
}
- });
+ } catch (Throwable e) {
+ reportWtf("Notifying CommonTimeManagementService running", e);
+ }
+ try {
+ if (textServiceManagerServiceF != null)
+ textServiceManagerServiceF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying TextServicesManagerService running", e);
+ }
+ try {
+ if (atlasF != null) atlasF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying AssetAtlasService running", e);
+ }
+ try {
+ // TODO(BT) Pass parameter to input manager
+ if (inputManagerF != null) inputManagerF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying InputManagerService running", e);
+ }
+ try {
+ if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying TelephonyRegistry running", e);
+ }
+ try {
+ if (mediaRouterF != null) mediaRouterF.systemRunning();
+ } catch (Throwable e) {
+ reportWtf("Notifying MediaRouterService running", e);
+ }
+
+ mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETE);
}
});
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 9a4d8d8..bef33b9 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -98,6 +98,13 @@
// which need debouncing.
private static final int UPDATE_DELAY = 1000;
+ // Time we received a request to enter USB accessory mode
+ private long mAccessoryModeRequestTime = 0;
+
+ // Timeout for entering USB request mode.
+ // Request is cancelled if host does not configure device within 10 seconds.
+ private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000;
+
private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
private UsbHandler mHandler;
@@ -205,6 +212,8 @@
}
private void startAccessoryMode() {
+ if (!mHasUsbAccessory) return;
+
mAccessoryStrings = nativeGetAccessoryStrings();
boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
// don't start accessory mode if our mandatory strings have not been set
@@ -223,6 +232,7 @@
}
if (functions != null) {
+ mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
setCurrentFunctions(functions, false);
}
}
@@ -456,6 +466,8 @@
}
private void setEnabledFunctions(String functions, boolean makeDefault) {
+ if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions
+ + " makeDefault: " + makeDefault);
// Do not update persystent.sys.usb.config if the device is booted up
// with OEM specific mode.
@@ -517,9 +529,17 @@
}
private void updateCurrentAccessory() {
- if (!mHasUsbAccessory) return;
+ // We are entering accessory mode if we have received a request from the host
+ // and the request has not timed out yet.
+ boolean enteringAccessoryMode =
+ mAccessoryModeRequestTime > 0 &&
+ SystemClock.elapsedRealtime() <
+ mAccessoryModeRequestTime + ACCESSORY_REQUEST_TIMEOUT;
- if (mConfigured) {
+ if (mConfigured && enteringAccessoryMode) {
+ // successfully entered accessory mode
+ mAccessoryModeRequestTime = 0;
+
if (mAccessoryStrings != null) {
mCurrentAccessory = new UsbAccessory(mAccessoryStrings);
Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
@@ -530,7 +550,7 @@
} else {
Slog.e(TAG, "nativeGetAccessoryStrings failed");
}
- } else if (!mConnected) {
+ } else if (!enteringAccessoryMode) {
// make sure accessory mode is off
// and restore default functions
Slog.d(TAG, "exited USB accessory mode");
@@ -560,6 +580,8 @@
}
}
+ if (DEBUG) Slog.d(TAG, "broadcasting " + intent + " connected: " + mConnected
+ + " configured: " + mConfigured);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
@@ -599,9 +621,7 @@
if (containsFunction(mCurrentFunctions,
UsbManager.USB_FUNCTION_ACCESSORY)) {
updateCurrentAccessory();
- }
-
- if (!mConnected) {
+ } else if (!mConnected) {
// restore defaults when USB is disconnected
setEnabledFunctions(mDefaultFunctions, false);
}