diff options
Diffstat (limited to 'services/java/com/android/server')
6 files changed, 103 insertions, 83 deletions
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index 59a540b..ad25657 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -22,6 +22,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -62,6 +63,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.util.AttributeSet; +import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.TypedValue; @@ -121,18 +123,15 @@ class AppWidgetService extends IAppWidgetService.Stub * globally and may lead us to leak AppWidgetService instances (if there were more than one). */ static class ServiceConnectionProxy implements ServiceConnection { - private final AppWidgetService mAppWidgetService; private final Pair<Integer, Intent.FilterComparison> mKey; private final IBinder mConnectionCb; - ServiceConnectionProxy(AppWidgetService appWidgetService, - Pair<Integer, Intent.FilterComparison> key, IBinder connectionCb) { - mAppWidgetService = appWidgetService; + ServiceConnectionProxy(Pair<Integer, Intent.FilterComparison> key, IBinder connectionCb) { mKey = key; mConnectionCb = connectionCb; } public void onServiceConnected(ComponentName name, IBinder service) { - IRemoteViewsAdapterConnection cb = + final IRemoteViewsAdapterConnection cb = IRemoteViewsAdapterConnection.Stub.asInterface(mConnectionCb); try { cb.onServiceConnected(service); @@ -141,19 +140,13 @@ class AppWidgetService extends IAppWidgetService.Stub } } public void onServiceDisconnected(ComponentName name) { - IRemoteViewsAdapterConnection cb = + disconnect(); + } + public void disconnect() { + final IRemoteViewsAdapterConnection cb = IRemoteViewsAdapterConnection.Stub.asInterface(mConnectionCb); try { cb.onServiceDisconnected(); - mAppWidgetService.mServiceConnectionUpdateHandler.post(new Runnable() { - public void run() { - // We don't want to touch mBoundRemoteViewsServices from any other thread - // so queue this to run on the main thread. - if (mAppWidgetService.mBoundRemoteViewsServices.containsKey(mKey)) { - mAppWidgetService.mBoundRemoteViewsServices.remove(mKey); - } - } - }); } catch (RemoteException e) { e.printStackTrace(); } @@ -163,7 +156,6 @@ class AppWidgetService extends IAppWidgetService.Stub // Manages connections to RemoteViewsServices private final HashMap<Pair<Integer, FilterComparison>, ServiceConnection> mBoundRemoteViewsServices = new HashMap<Pair<Integer,FilterComparison>,ServiceConnection>(); - private final Handler mServiceConnectionUpdateHandler = new Handler(); Context mContext; Locale mLocale; @@ -456,13 +448,24 @@ class AppWidgetService extends IAppWidgetService.Stub throw new IllegalArgumentException("Unknown component " + componentName); } - // Bind to the RemoteViewsService (which will trigger a callback to the - // RemoteViewsAdapter) + // If there is already a connection made for this service intent, then disconnect from + // that first. (This does not allow multiple connections to the same service under + // the same key) + ServiceConnectionProxy conn = null; Pair<Integer, FilterComparison> key = Pair.create(appWidgetId, new FilterComparison(intent)); - final ServiceConnection conn = new ServiceConnectionProxy(this, key, connection); + if (mBoundRemoteViewsServices.containsKey(key)) { + conn = (ServiceConnectionProxy) mBoundRemoteViewsServices.get(key); + conn.disconnect(); + mContext.unbindService(conn); + mBoundRemoteViewsServices.remove(key); + } + + // Bind to the RemoteViewsService (which will trigger a callback to the + // RemoteViewsAdapter.onServiceConnected()) final long token = Binder.clearCallingIdentity(); try { + conn = new ServiceConnectionProxy(key, connection); mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE); mBoundRemoteViewsServices.put(key, conn); } finally { @@ -473,37 +476,43 @@ class AppWidgetService extends IAppWidgetService.Stub public void unbindRemoteViewsService(int appWidgetId, Intent intent) { synchronized (mAppWidgetIds) { - AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); - if (id == null) { - throw new IllegalArgumentException("bad appWidgetId"); - } - // Unbind from the RemoteViewsService (which will trigger a callback to the bound // RemoteViewsAdapter) Pair<Integer, FilterComparison> key = Pair.create(appWidgetId, new FilterComparison(intent)); if (mBoundRemoteViewsServices.containsKey(key)) { - final ServiceConnection conn = mBoundRemoteViewsServices.get(key); - mBoundRemoteViewsServices.remove(key); - conn.onServiceDisconnected(null); + // We don't need to use the appWidgetId until after we are sure there is something + // to unbind. Note that this may mask certain issues with apps calling unbind() + // more than necessary. + AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); + if (id == null) { + throw new IllegalArgumentException("bad appWidgetId"); + } + + ServiceConnectionProxy conn = + (ServiceConnectionProxy) mBoundRemoteViewsServices.get(key); + conn.disconnect(); mContext.unbindService(conn); + mBoundRemoteViewsServices.remove(key); + } else { + Log.e("AppWidgetService", "Error (unbindRemoteViewsService): Connection not bound"); } } } private void unbindAppWidgetRemoteViewsServicesLocked(AppWidgetId id) { + int appWidgetId = id.appWidgetId; + // Unbind all connections to Services bound to this AppWidgetId Iterator<Pair<Integer, Intent.FilterComparison>> it = mBoundRemoteViewsServices.keySet().iterator(); - int appWidgetId = id.appWidgetId; - - // Unbind all connections to AppWidgets bound to this id while (it.hasNext()) { final Pair<Integer, Intent.FilterComparison> key = it.next(); if (key.first.intValue() == appWidgetId) { - final ServiceConnection conn = mBoundRemoteViewsServices.get(key); - it.remove(); - conn.onServiceDisconnected(null); + final ServiceConnectionProxy conn = (ServiceConnectionProxy) + mBoundRemoteViewsServices.get(key); + conn.disconnect(); mContext.unbindService(conn); + it.remove(); } } } diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index bd3c554..e689654 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -1152,7 +1152,17 @@ public class ConnectivityService extends IConnectivityManager.Stub { if (checkType == prevNetType) continue; if (mNetAttributes[checkType] == null) continue; if (!mNetAttributes[checkType].isDefault()) continue; - if (!mNetTrackers[checkType].isAvailable()) continue; + +// Enabling the isAvailable() optimization caused mobile to not get +// selected if it was in the middle of error handling. Specifically +// a moble connection that took 30 seconds to complete the DEACTIVATE_DATA_CALL +// would not be available and we wouldn't get connected to anything. +// So removing the isAvailable() optimization below for now. TODO: This +// optimization should work and we need to investigate why it doesn't work. +// This could be related to how DEACTIVATE_DATA_CALL is reporting its +// complete before it is really complete. +// if (!mNetTrackers[checkType].isAvailable()) continue; + // if (currentPriority >= mNetAttributes[checkType].mPriority) continue; NetworkStateTracker checkTracker = mNetTrackers[checkType]; diff --git a/services/java/com/android/server/ScreenRotationAnimation.java b/services/java/com/android/server/ScreenRotationAnimation.java index bef64b3..90318f1 100644 --- a/services/java/com/android/server/ScreenRotationAnimation.java +++ b/services/java/com/android/server/ScreenRotationAnimation.java @@ -102,7 +102,7 @@ class ScreenRotationAnimation { Slog.w(TAG, "Unable to allocate freeze surface", e); } - if (false) { + if (true) { try { int size = mOriginalWidth > mOriginalHeight ? mOriginalWidth : mOriginalHeight; mBlackSurface = new Surface(session, 0, "BlackSurface", diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java index 50ea3fa..bdaa3b0 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/java/com/android/server/StatusBarManagerService.java @@ -283,33 +283,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } - /** - * This is used for the automatic version of lights-out mode. Only call this from - * the window manager. - * - * @see setLightsOn(boolean) - */ - public void setActiveWindowIsFullscreen(boolean fullscreen) { - // We could get away with a separate permission here, but STATUS_BAR is - // signatureOrSystem which is probably good enough. There is no public API - // for this, so the question is a security issue, not an API compatibility issue. - enforceStatusBar(); - - synchronized (mLock) { - updateLightsOnLocked(!fullscreen); - } - } - - /** - * This is used for the user-controlled version of lights-out mode. Only call this from - * the status bar itself. - * - * We have two different functions here, because I think we're going to want to - * tweak the behavior when the user keeps turning lights-out mode off and the - * app keeps trying to turn it on. For now they can just fight it out. Having - * these two separte inputs will allow us to keep that change local to here. --joeo - */ public void setSystemUiVisibility(int vis) { + // also allows calls from window manager which is in this process. enforceStatusBarService(); synchronized (mLock) { diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 2c8403c..30a9432 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -1918,9 +1918,10 @@ public class WindowManagerService extends IWindowManager.Stub WindowState wb = localmWindows.get(foundI-1); if (wb.mBaseLayer < maxLayer && wb.mAttachedWindow != foundW && - wb.mAttachedWindow != foundW.mAttachedWindow && + (foundW.mAttachedWindow == null || + wb.mAttachedWindow != foundW.mAttachedWindow) && (wb.mAttrs.type != TYPE_APPLICATION_STARTING || - wb.mToken != foundW.mToken)) { + foundW.mToken == null || wb.mToken != foundW.mToken)) { // This window is not related to the previous one in any // interesting way, so stop here. break; @@ -5003,7 +5004,6 @@ public class WindowManagerService extends IWindowManager.Stub Bitmap rawss; int maxLayer = 0; - boolean foundApp; final Rect frame = new Rect(); float scale; @@ -5013,24 +5013,49 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mWindowMap) { long ident = Binder.clearCallingIdentity(); + dw = mDisplay.getWidth(); + dh = mDisplay.getHeight(); + int aboveAppLayer = mPolicy.windowTypeToLayerLw( WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; aboveAppLayer += TYPE_LAYER_MULTIPLIER; + boolean isImeTarget = mInputMethodTarget != null + && mInputMethodTarget.mAppToken != null + && mInputMethodTarget.mAppToken.appToken != null + && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken; + // Figure out the part of the screen that is actually the app. - for (int i=0; i<mWindows.size(); i++) { + boolean including = false; + for (int i=mWindows.size()-1; i>=0; i--) { WindowState ws = mWindows.get(i); if (ws.mSurface == null) { continue; } if (ws.mLayer >= aboveAppLayer) { - break; - } - if (appToken != null && (ws.mAppToken == null - || ws.mAppToken.token != appToken)) { continue; } + // When we will skip windows: when we are not including + // ones behind a window we didn't skip, and we are actually + // taking a screenshot of a specific app. + if (!including && appToken != null) { + // Also, we can possibly skip this window if it is not + // an IME target or the application for the screenshot + // is not the current IME target. + if (!ws.mIsImWindow || !isImeTarget) { + // And finally, this window is of no interest if it + // is not associated with the screenshot app. + if (ws.mAppToken == null || ws.mAppToken.token != appToken) { + continue; + } + } + } + + // We keep on including windows until we go past a full-screen + // window. + including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh); + if (maxLayer < ws.mAnimLayer) { maxLayer = ws.mAnimLayer; } @@ -5065,8 +5090,8 @@ public class WindowManagerService extends IWindowManager.Stub } // The screen shot will contain the entire screen. - dw = (int)(mDisplay.getWidth()*scale); - dh = (int)(mDisplay.getHeight()*scale); + dw = (int)(dw*scale); + dh = (int)(dh*scale); if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) { int tmp = dw; dw = dh; @@ -10856,17 +10881,19 @@ public class WindowManagerService extends IWindowManager.Stub mInputMonitor.updateInputWindowsLw(true /*force*/); setHoldScreenLocked(holdScreen != null); - if (screenBrightness < 0 || screenBrightness > 1.0f) { - mPowerManager.setScreenBrightnessOverride(-1); - } else { - mPowerManager.setScreenBrightnessOverride((int) - (screenBrightness * Power.BRIGHTNESS_ON)); - } - if (buttonBrightness < 0 || buttonBrightness > 1.0f) { - mPowerManager.setButtonBrightnessOverride(-1); - } else { - mPowerManager.setButtonBrightnessOverride((int) - (buttonBrightness * Power.BRIGHTNESS_ON)); + if (!mDisplayFrozen) { + if (screenBrightness < 0 || screenBrightness > 1.0f) { + mPowerManager.setScreenBrightnessOverride(-1); + } else { + mPowerManager.setScreenBrightnessOverride((int) + (screenBrightness * Power.BRIGHTNESS_ON)); + } + if (buttonBrightness < 0 || buttonBrightness > 1.0f) { + mPowerManager.setButtonBrightnessOverride(-1); + } else { + mPowerManager.setButtonBrightnessOverride((int) + (buttonBrightness * Power.BRIGHTNESS_ON)); + } } if (holdScreen != mHoldingScreenOn) { mHoldingScreenOn = holdScreen; diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 2040cbd..5b44d39 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -3187,7 +3187,6 @@ public class ActivityStack { EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY, System.identityHashCode(r), r.task.taskId, r.shortComponentName, reason); - r.task.numActivities--; if (index < (mHistory.size()-1)) { ActivityRecord next = (ActivityRecord)mHistory.get(index+1); if (next.task == r.task) { |