@Override public boolean onTouch(View view, MotionEvent event) { if (requestFocus && view != null) { view.requestFocus(); view.requestFocusFromTouch(); requestFocus = false; } // synchronized in handler.postTouchEvent() touchHandler.onTouch(event, this); if (sleepTime != 0) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } } return true; }
@TargetApi(Build.VERSION_CODES.KITKAT) private void clearInputMethodManagerLeak() { try { Object lock = mHField.get(inputMethodManager); // This is highly dependent on the InputMethodManager implementation. synchronized (lock) { View servedView = (View) mServedViewField.get(inputMethodManager); if (servedView != null) { boolean servedViewAttached = servedView.getWindowVisibility() != View.GONE; if (servedViewAttached) { // The view held by the IMM was replaced without a global focus change. Let's make // sure we get notified when that view detaches. // Avoid double registration. servedView.removeOnAttachStateChangeListener(this); servedView.addOnAttachStateChangeListener(this); } else { // servedView is not attached. InputMethodManager is being stupid! Activity activity = extractActivity(servedView.getContext()); if (activity == null || activity.getWindow() == null) { // Unlikely case. Let's finish the input anyways. finishInputLockedMethod.invoke(inputMethodManager); } else { View decorView = activity.getWindow().peekDecorView(); boolean windowAttached = decorView.getWindowVisibility() != View.GONE; if (!windowAttached) { finishInputLockedMethod.invoke(inputMethodManager); } else { decorView.requestFocusFromTouch(); } } } } } } catch (IllegalAccessException | InvocationTargetException unexpected) { Log.e("IMMLeaks", "Unexpected reflection exception", unexpected); } }
public AndroidInput( Application activity, Context context, Object view, AndroidApplicationConfiguration config) { // we hook into View, for LWPs we call onTouch below directly from // within the AndroidLivewallpaperEngine#onTouchEvent() method. if (view instanceof View) { View v = (View) view; v.setOnKeyListener(this); v.setOnTouchListener(this); v.setFocusable(true); v.setFocusableInTouchMode(true); v.requestFocus(); v.requestFocusFromTouch(); } this.config = config; this.onscreenKeyboard = new AndroidOnscreenKeyboard(context, new Handler(), this); for (int i = 0; i < realId.length; i++) realId[i] = -1; handle = new Handler(); this.app = activity; this.context = context; this.sleepTime = config.touchSleepTime; int sdkVersion = Integer.parseInt(android.os.Build.VERSION.SDK); if (sdkVersion >= 5) touchHandler = new AndroidMultiTouchHandler(); else touchHandler = new AndroidSingleTouchHandler(); hasMultitouch = touchHandler.supportsMultitouch(context); vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); int rotation = getRotation(); DisplayMode mode = app.getGraphics().getDesktopDisplayMode(); if (((rotation == 0 || rotation == 180) && (mode.width >= mode.height)) || ((rotation == 90 || rotation == 270) && (mode.width <= mode.height))) { nativeOrientation = Orientation.Landscape; } else { nativeOrientation = Orientation.Portrait; } }
/* * (non-Javadoc) * * @see * android.widget.AdapterView.OnItemClickListener#onItemClick(android * .widget.AdapterView, android.view.View, int, long) */ @Override public void onItemClick(android.widget.AdapterView<?> arg0, View v, int position, long arg3) { DialogMenuItem menuItem = (DialogMenuItem) arg0.getItemAtPosition(position); switch (menuItem.getMenuDialogAction()) { case 0: performWatchedToggle(); break; case 1: startDownload(); break; case 2: performAddToQueue(); break; case 3: performPlayTrailer(); break; case 4: performGoogleTVSecondScreen(); } v.requestFocusFromTouch(); dialog.dismiss(); }
/** * Emulates a directional pad event based on the given flick direction. * * @param direction A flick direction constant. */ private void changeFocus(int direction) { int keyCode = KeyEvent.KEYCODE_UNKNOWN; switch (direction) { case FlickGestureListener.FLICK_UP: keyCode = KeyEvent.KEYCODE_DPAD_UP; break; case FlickGestureListener.FLICK_RIGHT: keyCode = KeyEvent.KEYCODE_DPAD_RIGHT; break; case FlickGestureListener.FLICK_DOWN: keyCode = KeyEvent.KEYCODE_DPAD_DOWN; break; case FlickGestureListener.FLICK_LEFT: keyCode = KeyEvent.KEYCODE_DPAD_LEFT; break; default: // Invalid flick constant. return; } if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { final int keyCodeFinal = keyCode; // Exit from touch mode as gracefully as possible. if (mSelectedView != null) { ViewParent parent = mSelectedView.getParent(); mSelectedView.requestFocusFromTouch(); // If the selected view belongs to a list, make sure it's // selected within the list (since it's not focusable). // TODO(alanv): Check whether the prior call was successful? if (parent instanceof AbsListView) { AbsListView listParent = (AbsListView) parent; int position = listParent.getPositionForView(mSelectedView); listParent.setSelection(position); } } else { requestFocusFromTouch(); } // We have to send the key event on a separate thread, then return // to the main thread to synchronize the selected view with focus. new Thread() { @Override public void run() { mInstrumentation.sendKeyDownUpSync(keyCodeFinal); mHandler.post( new Runnable() { @Override public void run() { View newFocusedView = findFocus(); setSelectedView(newFocusedView, false); } }); } }.start(); } }