diff options
Diffstat (limited to 'services/java/com/android')
6 files changed, 278 insertions, 291 deletions
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 7028772..c365af5 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -1371,31 +1371,70 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } + @Override public boolean switchToLastInputMethod(IBinder token) { synchronized (mMethodMap) { final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked(); - if (lastIme == null) return false; - final InputMethodInfo lastImi = mMethodMap.get(lastIme.first); - if (lastImi == null) return false; - - final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId); - final int lastSubtypeHash = Integer.valueOf(lastIme.second); - // If the last IME is the same as the current IME and the last subtype is not defined, - // there is no need to switch to the last IME. - if (imiIdIsSame && lastSubtypeHash == NOT_A_SUBTYPE_ID) return false; + final InputMethodInfo lastImi; + if (lastIme != null) { + lastImi = mMethodMap.get(lastIme.first); + } else { + lastImi = null; + } + String targetLastImiId = null; + int subtypeId = NOT_A_SUBTYPE_ID; + if (lastIme != null && lastImi != null) { + final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId); + final int lastSubtypeHash = Integer.valueOf(lastIme.second); + final int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID + : mCurrentSubtype.hashCode(); + // If the last IME is the same as the current IME and the last subtype is not + // defined, there is no need to switch to the last IME. + if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) { + targetLastImiId = lastIme.first; + subtypeId = getSubtypeIdFromHashCode(lastImi, lastSubtypeHash); + } + } + + if (TextUtils.isEmpty(targetLastImiId) && !canAddToLastInputMethod(mCurrentSubtype)) { + // This is a safety net. If the currentSubtype can't be added to the history + // and the framework couldn't find the last ime, we will make the last ime be + // the most applicable enabled keyboard subtype of the system imes. + final List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked(); + if (enabled != null) { + final int N = enabled.size(); + final String locale = mCurrentSubtype == null + ? mRes.getConfiguration().locale.toString() + : mCurrentSubtype.getLocale(); + for (int i = 0; i < N; ++i) { + final InputMethodInfo imi = enabled.get(i); + if (imi.getSubtypeCount() > 0 && isSystemIme(imi)) { + InputMethodSubtype keyboardSubtype = + findLastResortApplicableSubtypeLocked(mRes, getSubtypes(imi), + SUBTYPE_MODE_KEYBOARD, locale, true); + if (keyboardSubtype != null) { + targetLastImiId = imi.getId(); + subtypeId = getSubtypeIdFromHashCode( + imi, keyboardSubtype.hashCode()); + if(keyboardSubtype.getLocale().equals(locale)) { + break; + } + } + } + } + } + } - int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID - : mCurrentSubtype.hashCode(); - if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) { + if (!TextUtils.isEmpty(targetLastImiId)) { if (DEBUG) { - Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second + ", from: " - + mCurMethodId + ", " + currentSubtypeHash); + Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second + + ", from: " + mCurMethodId + ", " + subtypeId); } - setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode( - lastImi, lastSubtypeHash)); + setInputMethodWithSubtypeId(token, targetLastImiId, subtypeId); return true; + } else { + return false; } - return false; } } @@ -2619,7 +2658,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub List<Pair<String, ArrayList<String>>> enabledImes = getEnabledInputMethodsAndSubtypeListLocked(); List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked(); - for (Pair<String, String> imeAndSubtype: subtypeHistory) { + for (Pair<String, String> imeAndSubtype : subtypeHistory) { final String imeInTheHistory = imeAndSubtype.first; // If imeId is empty, returns the first IME and subtype in the history if (TextUtils.isEmpty(imeId) || imeInTheHistory.equals(imeId)) { diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index a2d10df..41ec63a 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -568,31 +568,10 @@ public class WifiService extends IWifiManager.Stub { * @param wifiConfig SSID, security and channel details as * part of WifiConfiguration * @param enabled true to enable and false to disable - * @return {@code true} if the start operation was - * started or is already in the queue. */ - public synchronized boolean setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) { + public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) { enforceChangePermission(); - - if (enabled) { - /* Use default config if there is no existing config */ - if (wifiConfig == null && ((wifiConfig = getWifiApConfiguration()) == null)) { - wifiConfig = new WifiConfiguration(); - wifiConfig.SSID = mContext.getString(R.string.wifi_tether_configure_ssid_default); - wifiConfig.allowedKeyManagement.set(KeyMgmt.NONE); - } - /* - * Caller might not have WRITE_SECURE_SETTINGS, - * only CHANGE_WIFI_STATE is enforced - */ - long ident = Binder.clearCallingIdentity(); - setWifiApConfiguration(wifiConfig); - Binder.restoreCallingIdentity(ident); - } - mWifiStateMachine.setWifiApEnabled(wifiConfig, enabled); - - return true; } /** @@ -612,38 +591,20 @@ public class WifiService extends IWifiManager.Stub { * see {@link WifiManager#getWifiApConfiguration()} * @return soft access point configuration */ - public synchronized WifiConfiguration getWifiApConfiguration() { - final ContentResolver cr = mContext.getContentResolver(); - WifiConfiguration wifiConfig = new WifiConfiguration(); - int authType; - try { - wifiConfig.SSID = Settings.Secure.getString(cr, Settings.Secure.WIFI_AP_SSID); - if (wifiConfig.SSID == null) - return null; - authType = Settings.Secure.getInt(cr, Settings.Secure.WIFI_AP_SECURITY); - wifiConfig.allowedKeyManagement.set(authType); - wifiConfig.preSharedKey = Settings.Secure.getString(cr, Settings.Secure.WIFI_AP_PASSWD); - return wifiConfig; - } catch (Settings.SettingNotFoundException e) { - Slog.e(TAG,"AP settings not found, returning"); - return null; - } + public WifiConfiguration getWifiApConfiguration() { + enforceAccessPermission(); + return mWifiStateMachine.syncGetWifiApConfiguration(mWifiStateMachineChannel); } /** * see {@link WifiManager#setWifiApConfiguration(WifiConfiguration)} * @param wifiConfig WifiConfiguration details for soft access point */ - public synchronized void setWifiApConfiguration(WifiConfiguration wifiConfig) { + public void setWifiApConfiguration(WifiConfiguration wifiConfig) { enforceChangePermission(); - final ContentResolver cr = mContext.getContentResolver(); if (wifiConfig == null) return; - int authType = wifiConfig.getAuthType(); - Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_SSID, wifiConfig.SSID); - Settings.Secure.putInt(cr, Settings.Secure.WIFI_AP_SECURITY, authType); - if (authType != KeyMgmt.NONE) - Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_PASSWD, wifiConfig.preSharedKey); + mWifiStateMachine.setWifiApConfiguration(wifiConfig); } /** diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java index fb97089..4c7f595 100644 --- a/services/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/java/com/android/server/accessibility/TouchExplorer.java @@ -110,9 +110,6 @@ public class TouchExplorer implements Explorer { // Temporary array for storing pointer IDs. private final int[] mTempPointerIds = new int[MAX_POINTER_COUNT]; - // Temporary array for mapping new to old pointer IDs while filtering inactive pointers. - private final int [] mTempNewToOldPointerIndexMap = new int[MAX_POINTER_COUNT]; - // Temporary array for storing PointerProperties private final PointerProperties[] mTempPointerProperties = PointerProperties.createArray(MAX_POINTER_COUNT); @@ -229,7 +226,7 @@ public class TouchExplorer implements Explorer { // Send a hover for every finger down so the user gets feedback // where she is currently touching. mSendHoverDelayed.forceSendAndRemove(); - mSendHoverDelayed.post(event, MotionEvent.ACTION_HOVER_ENTER, 0, policyFlags, + mSendHoverDelayed.post(event, MotionEvent.ACTION_HOVER_ENTER, 1, policyFlags, DELAY_SEND_HOVER_MOVE); } break; case MotionEvent.ACTION_POINTER_DOWN: { @@ -243,13 +240,13 @@ public class TouchExplorer implements Explorer { // accessibility event from the hovered view. mSendHoverDelayed.remove(); final int pointerId = pointerTracker.getPrimaryActivePointerId(); - final int pointerIndex = event.findPointerIndex(pointerId); + final int pointerIdBits = (1 << pointerId); final int lastAction = pointerTracker.getLastInjectedHoverAction(); // If a schedules hover enter for another pointer is delivered we send move. final int action = (lastAction == MotionEvent.ACTION_HOVER_ENTER) ? MotionEvent.ACTION_HOVER_MOVE : MotionEvent.ACTION_HOVER_ENTER; - mSendHoverDelayed.post(event, action, pointerIndex, policyFlags, + mSendHoverDelayed.post(event, action, pointerIdBits, policyFlags, DELAY_SEND_HOVER_MOVE); if (mLastTouchExploreEvent == null) { @@ -268,14 +265,14 @@ public class TouchExplorer implements Explorer { } } break; case MotionEvent.ACTION_MOVE: { + final int pointerId = pointerTracker.getPrimaryActivePointerId(); + final int pointerIndex = event.findPointerIndex(pointerId); + final int pointerIdBits = (1 << pointerId); switch (activePointerCount) { case 0: { /* do nothing - no active pointers so we swallow the event */ } break; case 1: { - final int pointerId = pointerTracker.getPrimaryActivePointerId(); - final int pointerIndex = event.findPointerIndex(pointerId); - // Detect touch exploration gesture start by having one active pointer // that moved more than a given distance. if (!mTouchExploreGestureInProgress) { @@ -290,12 +287,19 @@ public class TouchExplorer implements Explorer { sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_START); // Make sure the scheduled down/move event is sent. mSendHoverDelayed.forceSendAndRemove(); - sendHoverEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIndex, + // If we have transitioned to exploring state from another one + // we need to send a hover enter event here. + final int lastAction = mPointerTracker.getLastInjectedHoverAction(); + if (lastAction == MotionEvent.ACTION_HOVER_EXIT) { + sendMotionEvent(event, MotionEvent.ACTION_HOVER_ENTER, + pointerIdBits, policyFlags); + } + sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); } } else { // Touch exploration gesture in progress so send a hover event. - sendHoverEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIndex, + sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); } @@ -337,13 +341,10 @@ public class TouchExplorer implements Explorer { } } break; case 2: { - // Make sure the scheduled hover enter is delivered. mSendHoverDelayed.forceSendAndRemove(); // We want to no longer hover over the location so subsequent // touch at the same spot will generate a hover enter. - final int pointerId = pointerTracker.getPrimaryActivePointerId(); - final int pointerIndex = event.findPointerIndex(pointerId); - sendHoverEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIndex, + sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); if (isDraggingGesture(event)) { @@ -354,8 +355,9 @@ public class TouchExplorer implements Explorer { sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END); mTouchExploreGestureInProgress = false; } - mDraggingPointerId = pointerTracker.getPrimaryActivePointerId(); - sendDragEvent(event, MotionEvent.ACTION_DOWN, policyFlags); + mDraggingPointerId = pointerId; + sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits, + policyFlags); } else { // Two pointers moving arbitrary are delegated to the view hierarchy. mCurrentState = STATE_DELEGATING; @@ -367,13 +369,10 @@ public class TouchExplorer implements Explorer { } } break; default: { - // Make sure the scheduled hover enter is delivered. mSendHoverDelayed.forceSendAndRemove(); // We want to no longer hover over the location so subsequent // touch at the same spot will generate a hover enter. - final int pointerId = pointerTracker.getPrimaryActivePointerId(); - final int pointerIndex = event.findPointerIndex(pointerId); - sendHoverEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIndex, + sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); // More than two pointers are delegated to the view hierarchy. @@ -389,6 +388,8 @@ public class TouchExplorer implements Explorer { } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: { + final int pointerId = pointerTracker.getLastReceivedUpPointerId(); + final int pointerIdBits = (1 << pointerId); switch (activePointerCount) { case 0: { // If the pointer that went up was not active we have nothing to do. @@ -404,7 +405,6 @@ public class TouchExplorer implements Explorer { // Detect whether to activate i.e. click on the last explored location. if (mLastTouchExploreEvent != null) { - final int pointerId = pointerTracker.getLastReceivedUpPointerId(); // If the down was not in the time slop => nothing else to do. final long eventTime = @@ -413,7 +413,11 @@ public class TouchExplorer implements Explorer { final long deltaTime = eventTime - exploreTime; if (deltaTime > ACTIVATION_TIME_SLOP) { mSendHoverDelayed.forceSendAndRemove(); - scheduleHoverExit(event, policyFlags); + final int lastAction = mPointerTracker.getLastInjectedHoverAction(); + if (lastAction != MotionEvent.ACTION_HOVER_EXIT) { + sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, + pointerIdBits, policyFlags); + } mLastTouchExploreEvent = MotionEvent.obtain(event); break; } @@ -427,7 +431,11 @@ public class TouchExplorer implements Explorer { final float deltaMove = (float) Math.hypot(deltaX, deltaY); if (deltaMove > mTouchExplorationTapSlop) { mSendHoverDelayed.forceSendAndRemove(); - scheduleHoverExit(event, policyFlags); + final int lastAction = mPointerTracker.getLastInjectedHoverAction(); + if (lastAction != MotionEvent.ACTION_HOVER_EXIT) { + sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, + pointerIdBits, policyFlags); + } mLastTouchExploreEvent = MotionEvent.obtain(event); break; } @@ -438,7 +446,11 @@ public class TouchExplorer implements Explorer { mLastTouchExploreEvent = null; } else { mSendHoverDelayed.forceSendAndRemove(); - scheduleHoverExit(event, policyFlags); + final int lastAction = mPointerTracker.getLastInjectedHoverAction(); + if (lastAction != MotionEvent.ACTION_HOVER_EXIT) { + sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, + pointerIdBits, policyFlags); + } mLastTouchExploreEvent = MotionEvent.obtain(event); } } break; @@ -448,8 +460,8 @@ public class TouchExplorer implements Explorer { final int lastAction = pointerTracker.getLastInjectedHoverAction(); if (lastAction != MotionEvent.ACTION_HOVER_EXIT) { final int pointerId = pointerTracker.getPrimaryActivePointerId(); - final int pointerIndex = event.findPointerIndex(pointerId); - sendHoverEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIndex, + final int pointerIdBits = (1 << pointerId); + sendMotionEvent(event, MotionEvent.ACTION_HOVER_EXIT, pointerIdBits, policyFlags); } clear(); @@ -464,6 +476,7 @@ public class TouchExplorer implements Explorer { * @param policyFlags The policy flags associated with the event. */ private void handleMotionEventStateDragging(MotionEvent event, int policyFlags) { + final int pointerIdBits = (1 << mDraggingPointerId); switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: { throw new IllegalStateException("Dragging state can be reached only if two " @@ -473,7 +486,7 @@ public class TouchExplorer implements Explorer { // We are in dragging state so we have two pointers and another one // goes down => delegate the three pointers to the view hierarchy mCurrentState = STATE_DELEGATING; - sendDragEvent(event, MotionEvent.ACTION_UP, policyFlags); + sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); sendDownForAllActiveNotInjectedPointers(event, policyFlags); } break; case MotionEvent.ACTION_MOVE: { @@ -482,13 +495,15 @@ public class TouchExplorer implements Explorer { case 2: { if (isDraggingGesture(event)) { // If still dragging send a drag event. - sendDragEvent(event, MotionEvent.ACTION_MOVE, policyFlags); + sendMotionEvent(event, MotionEvent.ACTION_MOVE, pointerIdBits, + policyFlags); } else { // The two pointers are moving either in different directions or // no close enough => delegate the gesture to the view hierarchy. mCurrentState = STATE_DELEGATING; // Send an event to the end of the drag gesture. - sendDragEvent(event, MotionEvent.ACTION_UP, policyFlags); + sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, + policyFlags); // Deliver all active pointers to the view hierarchy. sendDownForAllActiveNotInjectedPointers(event, policyFlags); } @@ -496,7 +511,8 @@ public class TouchExplorer implements Explorer { default: { mCurrentState = STATE_DELEGATING; // Send an event to the end of the drag gesture. - sendDragEvent(event, MotionEvent.ACTION_UP, policyFlags); + sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, + policyFlags); // Deliver all active pointers to the view hierarchy. sendDownForAllActiveNotInjectedPointers(event, policyFlags); } @@ -505,7 +521,7 @@ public class TouchExplorer implements Explorer { case MotionEvent.ACTION_POINTER_UP: { mCurrentState = STATE_TOUCH_EXPLORING; // Send an event to the end of the drag gesture. - sendDragEvent(event, MotionEvent.ACTION_UP, policyFlags); + sendMotionEvent(event, MotionEvent.ACTION_UP, pointerIdBits, policyFlags); } break; case MotionEvent.ACTION_CANCEL: { clear(); @@ -551,23 +567,6 @@ public class TouchExplorer implements Explorer { } /** - * Schedules a hover up event so subsequent poking on the same location after - * the scheduled delay will perform exploration. - * - * @param prototype The prototype from which to create the injected events. - * @param policyFlags The policy flags associated with the event. - */ - private void scheduleHoverExit(MotionEvent prototype, - int policyFlags) { - final int pointerId = mPointerTracker.getLastReceivedUpPointerId(); - final int pointerIndex = prototype.findPointerIndex(pointerId); - // We want to no longer hover over the location so subsequent - // touch at the same spot will generate a hover enter. - mSendHoverDelayed.post(prototype, MotionEvent.ACTION_HOVER_EXIT, - pointerIndex, policyFlags, ACTIVATION_TIME_SLOP); - } - - /** * Sends down events to the view hierarchy for all active pointers which are * not already being delivered i.e. pointers that are not yet injected. * @@ -600,9 +599,9 @@ public class TouchExplorer implements Explorer { final long downTime = pointerTracker.getLastInjectedDownEventTime(); final int action = computeInjectionAction(MotionEvent.ACTION_DOWN, pointerDataIndex); final int pointerCount = pointerDataIndex + 1; - final long pointerDownTime = SystemClock.uptimeMillis(); + final long eventTime = SystemClock.uptimeMillis(); - MotionEvent event = MotionEvent.obtain(downTime, pointerDownTime, + MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, pointerCount, pointerProperties, pointerCoords, prototype.getMetaState(), prototype.getButtonState(), prototype.getXPrecision(), prototype.getYPrecision(), prototype.getDeviceId(), @@ -680,89 +679,18 @@ public class TouchExplorer implements Explorer { return; } - // Filter out inactive pointers from the event and inject it. - final PointerProperties[] pointerProperties = mTempPointerProperties; - final PointerCoords[] pointerCoords = mTempPointerCoords; - int [] newToOldPointerIndexMap = mTempNewToOldPointerIndexMap; - int newPointerIndex = 0; - int actionIndex = prototype.getActionIndex(); - - final int oldPointerCount = prototype.getPointerCount(); - for (int oldPointerIndex = 0; oldPointerIndex < oldPointerCount; oldPointerIndex++) { - final int pointerId = prototype.getPointerId(oldPointerIndex); - + int pointerIdBits = 0; + final int pointerCount = prototype.getPointerCount(); + for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) { + final int pointerId = prototype.getPointerId(pointerIndex); // If the pointer is inactive or the pointer that just went up // was inactive we strip the pointer data from the event. - if (!pointerTracker.isActiveOrWasLastActiveUpPointer(pointerId)) { - if (oldPointerIndex <= prototype.getActionIndex()) { - actionIndex--; - } - continue; + if (pointerTracker.isActiveOrWasLastActiveUpPointer(pointerId)) { + pointerIdBits |= (1 << pointerId); } - - newToOldPointerIndexMap[newPointerIndex] = oldPointerIndex; - prototype.getPointerProperties(oldPointerIndex, pointerProperties[newPointerIndex]); - prototype.getPointerCoords(oldPointerIndex, pointerCoords[newPointerIndex]); - - newPointerIndex++; - } - - // If we skipped all pointers => nothing to do. - if (newPointerIndex == 0) { - return; } - // Populate and inject the event. - final long downTime = pointerTracker.getLastInjectedDownEventTime(); - final int action = computeInjectionAction(prototype.getActionMasked(), actionIndex); - final int newPointerCount = newPointerIndex; - MotionEvent prunedEvent = MotionEvent.obtain(downTime, prototype.getEventTime(), action, - newPointerCount, pointerProperties, pointerCoords, - prototype.getMetaState(), prototype.getButtonState(), - prototype.getXPrecision(), prototype.getYPrecision(), prototype.getDeviceId(), - prototype.getEdgeFlags(), prototype.getSource(),prototype.getFlags()); - - // Add the filtered history. - final int historySize = prototype.getHistorySize(); - for (int historyIndex = 0; historyIndex < historySize; historyIndex++) { - for (int pointerIndex = 0; pointerIndex < newPointerCount; pointerIndex++) { - final int oldPointerIndex = newToOldPointerIndexMap[pointerIndex]; - prototype.getPointerCoords(oldPointerIndex, pointerCoords[pointerIndex]); - } - final long historicalTime = prototype.getHistoricalEventTime(historyIndex); - prunedEvent.addBatch(historicalTime, pointerCoords, 0); - } - - sendMotionEvent(prunedEvent, policyFlags); - prunedEvent.recycle(); - } - - /** - * Sends a dragging event from a two pointer event. The two pointers are - * merged into one and delivered to the view hierarchy. Through the entire - * drag gesture the pointer id delivered to the view hierarchy is the same. - * - * @param prototype The prototype from which to create the injected event. - * @param action The dragging action that is to be injected. - * @param policyFlags The policy flags associated with the event. - */ - private void sendDragEvent(MotionEvent prototype, int action, int policyFlags) { - final PointerProperties[] pointerProperties = mTempPointerProperties; - final PointerCoords[] pointerCoords = mTempPointerCoords; - final int pointerId = mDraggingPointerId; - final int pointerIndex = prototype.findPointerIndex(pointerId); - - // Populate the event with the date of the dragging pointer and inject it. - prototype.getPointerProperties(pointerIndex, pointerProperties[0]); - prototype.getPointerCoords(pointerIndex, pointerCoords[0]); - - MotionEvent event = MotionEvent.obtain(prototype.getDownTime(), - prototype.getEventTime(), action, 1, pointerProperties, pointerCoords, - prototype.getMetaState(), prototype.getButtonState(), - prototype.getXPrecision(), prototype.getYPrecision(), - prototype.getDeviceId(), prototype.getEdgeFlags(), prototype.getSource(), - prototype.getFlags()); - + MotionEvent event = prototype.split(pointerIdBits); sendMotionEvent(event, policyFlags); event.recycle(); } @@ -798,32 +726,20 @@ public class TouchExplorer implements Explorer { } /** - * Sends a hover event. + * Sends an event. * - * @param prototype The prototype from which to create the injected event. - * @param action The hover action. - * @param pointerIndex The action pointer index. + * @param event The event to send. + * @param action The action of the event. + * @param pointerIdBits The bits of the pointers to send. * @param policyFlags The policy flags associated with the event. */ - private void sendHoverEvent(MotionEvent prototype, int action, int pointerIndex, int - policyFlags) { - final PointerProperties[] pointerProperties = mTempPointerProperties; - final PointerCoords[] pointerCoords = mTempPointerCoords; - - prototype.getPointerProperties(pointerIndex, pointerProperties[0]); - prototype.getPointerCoords(pointerIndex, pointerCoords[0]); - - final long downTime = mPointerTracker.getLastInjectedDownEventTime(); - - // Populate and inject a hover event. - MotionEvent hoverEvent = MotionEvent.obtain(downTime, prototype.getEventTime(), action, - 1, pointerProperties, pointerCoords, - prototype.getMetaState(), prototype.getButtonState(), - prototype.getXPrecision(), prototype.getYPrecision(), prototype.getDeviceId(), - prototype.getEdgeFlags(), prototype.getSource(), prototype.getFlags()); - - sendMotionEvent(hoverEvent, policyFlags); - hoverEvent.recycle(); + private void sendMotionEvent(MotionEvent prototype, int action, int pointerIdBits, + int policyFlags) { + MotionEvent event = prototype.split(pointerIdBits); + event.setDownTime(mPointerTracker.getLastInjectedDownEventTime()); + event.setAction(action); + sendMotionEvent(event, policyFlags); + event.recycle(); } /** @@ -1381,6 +1297,9 @@ public class TouchExplorer implements Explorer { final int pointerId = event.getPointerId(pointerIndex); final int pointerFlag = (1 << pointerId); mInjectedPointersDown &= ~pointerFlag; + if (mInjectedPointersDown == 0) { + mLastInjectedDownEventTime = 0; + } } /** @@ -1481,15 +1400,15 @@ public class TouchExplorer implements Explorer { private MotionEvent mEvent; private int mAction; - private int mPointerIndex; + private int mPointerIdBits; private int mPolicyFlags; - public void post(MotionEvent prototype, int action, int pointerIndex, int policyFlags, + public void post(MotionEvent prototype, int action, int pointerIdBits, int policyFlags, long delay) { remove(); mEvent = MotionEvent.obtain(prototype); mAction = action; - mPointerIndex = pointerIndex; + mPointerIdBits = pointerIdBits; mPolicyFlags = policyFlags; mHandler.postDelayed(this, delay); } @@ -1510,7 +1429,7 @@ public class TouchExplorer implements Explorer { mEvent.recycle(); mEvent = null; mAction = 0; - mPointerIndex = -1; + mPointerIdBits = -1; mPolicyFlags = 0; } @@ -1532,7 +1451,7 @@ public class TouchExplorer implements Explorer { } } - sendHoverEvent(mEvent, mAction, mPointerIndex, mPolicyFlags); + sendMotionEvent(mEvent, mAction, mPointerIdBits, mPolicyFlags); clear(); } } diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index de439ca..e1fbe1c 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -59,6 +59,7 @@ import android.content.pm.PackageInfoLite; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.PackageStats; +import android.content.pm.ParceledListSlice; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; @@ -2371,63 +2372,112 @@ public class PackageManagerService extends IPackageManager.Stub { } } - public List<PackageInfo> getInstalledPackages(int flags) { - final ArrayList<PackageInfo> finalList = new ArrayList<PackageInfo>(); + private static final int getContinuationPoint(final String[] keys, final String key) { + final int index; + if (key == null) { + index = 0; + } else { + final int insertPoint = Arrays.binarySearch(keys, key); + if (insertPoint < 0) { + index = -insertPoint; + } else { + index = insertPoint + 1; + } + } + return index; + } + + public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, String lastRead) { + final ParceledListSlice<PackageInfo> list = new ParceledListSlice<PackageInfo>(); + final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; + final String[] keys; // writer synchronized (mPackages) { - if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { - final Iterator<PackageSetting> i = mSettings.mPackages.values().iterator(); - while (i.hasNext()) { - final PackageSetting ps = i.next(); - final PackageInfo psPkg = generatePackageInfoFromSettingsLPw(ps.name, flags); - if (psPkg != null) { - finalList.add(psPkg); - } - } + if (listUninstalled) { + keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]); } else { - final Iterator<PackageParser.Package> i = mPackages.values().iterator(); - while (i.hasNext()) { - final PackageParser.Package p = i.next(); - if (p.applicationInfo != null) { - final PackageInfo pi = generatePackageInfo(p, flags); - if (pi != null) { - finalList.add(pi); - } + keys = mPackages.keySet().toArray(new String[mPackages.size()]); + } + + Arrays.sort(keys); + int i = getContinuationPoint(keys, lastRead); + final int N = keys.length; + + while (i < N) { + final String packageName = keys[i++]; + + PackageInfo pi = null; + if (listUninstalled) { + final PackageSetting ps = mSettings.mPackages.get(packageName); + if (ps != null) { + pi = generatePackageInfoFromSettingsLPw(ps.name, flags); + } + } else { + final PackageParser.Package p = mPackages.get(packageName); + if (p != null) { + pi = generatePackageInfo(p, flags); } } + + if (pi != null && !list.append(pi)) { + break; + } + } + + if (i == N) { + list.setLastSlice(true); } } - return finalList; + + return list; } - public List<ApplicationInfo> getInstalledApplications(int flags) { - final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); + public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, + String lastRead) { + final ParceledListSlice<ApplicationInfo> list = new ParceledListSlice<ApplicationInfo>(); + final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; + final String[] keys; + // writer - synchronized(mPackages) { - if((flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0) { - final Iterator<PackageSetting> i = mSettings.mPackages.values().iterator(); - while (i.hasNext()) { - final PackageSetting ps = i.next(); - ApplicationInfo ai = generateApplicationInfoFromSettingsLPw(ps.name, flags); - if(ai != null) { - finalList.add(ai); - } - } + synchronized (mPackages) { + if (listUninstalled) { + keys = mSettings.mPackages.keySet().toArray(new String[mSettings.mPackages.size()]); } else { - final Iterator<PackageParser.Package> i = mPackages.values().iterator(); - while (i.hasNext()) { - final PackageParser.Package p = i.next(); - if (p.applicationInfo != null) { - ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags); - if(ai != null) { - finalList.add(ai); - } + keys = mPackages.keySet().toArray(new String[mPackages.size()]); + } + + Arrays.sort(keys); + int i = getContinuationPoint(keys, lastRead); + final int N = keys.length; + + while (i < N) { + final String packageName = keys[i++]; + + ApplicationInfo ai = null; + if (listUninstalled) { + final PackageSetting ps = mSettings.mPackages.get(packageName); + if (ps != null) { + ai = generateApplicationInfoFromSettingsLPw(ps.name, flags); + } + } else { + final PackageParser.Package p = mPackages.get(packageName); + if (p != null) { + ai = PackageParser.generateApplicationInfo(p, flags); } } + + if (ai != null && !list.append(ai)) { + break; + } + } + + if (i == N) { + list.setLastSlice(true); } } - return finalList; + + return list; } public List<ApplicationInfo> getPersistentApplications(int flags) { @@ -8052,7 +8102,8 @@ public class PackageManagerService extends IPackageManager.Stub { } public UserInfo createUser(String name, int flags) { - UserInfo userInfo = mUserManager.createUser(name, flags, getInstalledApplications(0)); + // TODO(kroot): fix this API + UserInfo userInfo = mUserManager.createUser(name, flags, new ArrayList<ApplicationInfo>()); return userInfo; } diff --git a/services/java/com/android/server/wm/ViewServer.java b/services/java/com/android/server/wm/ViewServer.java index 9fb35b9..70cb26a 100644 --- a/services/java/com/android/server/wm/ViewServer.java +++ b/services/java/com/android/server/wm/ViewServer.java @@ -73,19 +73,6 @@ class ViewServer implements Runnable { private ExecutorService mThreadPool; /** - * Creates a new ViewServer associated with the specified window manager. - * The server uses the default port {@link #VIEW_SERVER_DEFAULT_PORT}. The server - * is not started by default. - * - * @param windowManager The window manager used to communicate with the views. - * - * @see #start() - */ - ViewServer(WindowManagerService windowManager) { - this(windowManager, VIEW_SERVER_DEFAULT_PORT); - } - - /** * Creates a new ViewServer associated with the specified window manager on the * specified local port. The server is not started by default. * @@ -177,7 +164,7 @@ class ViewServer implements Runnable { // Any uncaught exception will crash the system process try { Socket client = mServer.accept(); - if(mThreadPool != null) { + if (mThreadPool != null) { mThreadPool.submit(new ViewServerWorker(client)); } else { try { @@ -220,6 +207,7 @@ class ViewServer implements Runnable { private Socket mClient; private boolean mNeedWindowListUpdate; private boolean mNeedFocusedWindowUpdate; + public ViewServerWorker(Socket client) { mClient = client; mNeedWindowListUpdate = false; @@ -255,7 +243,7 @@ class ViewServer implements Runnable { result = mWindowManager.viewServerListWindows(mClient); } else if (COMMAND_WINDOW_MANAGER_GET_FOCUS.equalsIgnoreCase(command)) { result = mWindowManager.viewServerGetFocusedWindow(mClient); - } else if(COMMAND_WINDOW_MANAGER_AUTOLIST.equalsIgnoreCase(command)) { + } else if (COMMAND_WINDOW_MANAGER_AUTOLIST.equalsIgnoreCase(command)) { result = windowManagerAutolistLoop(); } else { result = mWindowManager.viewServerWindowCommand(mClient, @@ -263,7 +251,7 @@ class ViewServer implements Runnable { } if (!result) { - Slog.w(LOG_TAG, "An error occured with the command: " + command); + Slog.w(LOG_TAG, "An error occurred with the command: " + command); } } catch(IOException e) { Slog.w(LOG_TAG, "Connection error: ", e); @@ -321,11 +309,11 @@ class ViewServer implements Runnable { needFocusedWindowUpdate = true; } } - if(needWindowListUpdate) { + if (needWindowListUpdate) { out.write("LIST UPDATE\n"); out.flush(); } - if(needFocusedWindowUpdate) { + if (needFocusedWindowUpdate) { out.write("FOCUS UPDATE\n"); out.flush(); } @@ -337,6 +325,7 @@ class ViewServer implements Runnable { try { out.close(); } catch (IOException e) { + // Ignore } } mWindowManager.removeWindowChangeListener(this); diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 9890bec..92c490e 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -4783,8 +4783,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mWindowMap) { long ident = Binder.clearCallingIdentity(); - dw = mPolicy.getNonDecorDisplayWidth(mCurDisplayWidth); - dh = mPolicy.getNonDecorDisplayHeight(mCurDisplayHeight); + dw = mPolicy.getNonDecorDisplayWidth(mRotation, mCurDisplayWidth); + dh = mPolicy.getNonDecorDisplayHeight(mRotation, mCurDisplayHeight); int aboveAppLayer = mPolicy.windowTypeToLayerLw( WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER @@ -5501,6 +5501,14 @@ public class WindowManagerService extends IWindowManager.Stub return config; } + private int reduceConfigWidthSize(int curSize, int rotation, float density, int dw) { + int size = (int)(mPolicy.getConfigDisplayWidth(rotation, dw) / density); + if (size < curSize) { + curSize = size; + } + return curSize; + } + boolean computeNewConfigurationLocked(Configuration config) { if (mDisplay == null) { return false; @@ -5551,14 +5559,37 @@ public class WindowManagerService extends IWindowManager.Stub // Override display width and height with what we are computing, // to be sure they remain consistent. - dm.widthPixels = dm.realWidthPixels = mPolicy.getNonDecorDisplayWidth(dw); - dm.heightPixels = dm.realHeightPixels = mPolicy.getNonDecorDisplayHeight(dh); + dm.widthPixels = dm.realWidthPixels = mPolicy.getNonDecorDisplayWidth( + mRotation, dw); + dm.heightPixels = dm.realHeightPixels = mPolicy.getNonDecorDisplayHeight( + mRotation, dh); mCompatibleScreenScale = CompatibilityInfo.updateCompatibleScreenFrame( dm, mCompatibleScreenFrame, null); - config.screenWidthDp = (int)(dm.widthPixels / dm.density); - config.screenHeightDp = (int)(dm.heightPixels / dm.density); + config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(mRotation, dw) / dm.density); + config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(mRotation, dh) / dm.density); + + // We need to determine the smallest width that will occur under normal + // operation. To this, start with the base screen size and compute the + // width under the different possible rotations. We need to un-rotate + // the current screen dimensions before doing this. + int unrotDw, unrotDh; + if (rotated) { + unrotDw = dh; + unrotDh = dw; + } else { + unrotDw = dw; + unrotDh = dh; + } + config.smallestScreenWidthDp = reduceConfigWidthSize(unrotDw, + Surface.ROTATION_0, dm.density, unrotDw); + config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp, + Surface.ROTATION_90, dm.density, unrotDh); + config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp, + Surface.ROTATION_180, dm.density, unrotDw); + config.smallestScreenWidthDp = reduceConfigWidthSize(config.smallestScreenWidthDp, + Surface.ROTATION_270, dm.density, unrotDh); // Compute the screen layout size class. int screenLayout; @@ -6810,9 +6841,6 @@ public class WindowManagerService extends IWindowManager.Stub final int dw = mCurDisplayWidth; final int dh = mCurDisplayHeight; - final int innerDw = mPolicy.getNonDecorDisplayWidth(dw); - final int innerDh = mPolicy.getNonDecorDisplayHeight(dh); - final int N = mWindows.size(); int i; @@ -6933,8 +6961,8 @@ public class WindowManagerService extends IWindowManager.Stub final int dw = mCurDisplayWidth; final int dh = mCurDisplayHeight; - final int innerDw = mPolicy.getNonDecorDisplayWidth(dw); - final int innerDh = mPolicy.getNonDecorDisplayHeight(dh); + final int innerDw = mPolicy.getNonDecorDisplayWidth(mRotation, dw); + final int innerDh = mPolicy.getNonDecorDisplayHeight(mRotation, dh); int i; |
