diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-02-13 12:57:50 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-02-13 12:57:50 -0800 |
commit | da996f390e17e16f2dfa60e972e7ebc4f868f37e (patch) | |
tree | 00a0f15270d4c7b619fd34d8383257e1761082f4 /core/java/android/view | |
parent | d24b8183b93e781080b2c16c487e60d51c12da31 (diff) | |
download | frameworks_base-da996f390e17e16f2dfa60e972e7ebc4f868f37e.zip frameworks_base-da996f390e17e16f2dfa60e972e7ebc4f868f37e.tar.gz frameworks_base-da996f390e17e16f2dfa60e972e7ebc4f868f37e.tar.bz2 |
auto import from //branches/cupcake/...@131421
Diffstat (limited to 'core/java/android/view')
-rw-r--r-- | core/java/android/view/HapticFeedbackConstants.java | 45 | ||||
-rw-r--r-- | core/java/android/view/IWindowSession.aidl | 3 | ||||
-rw-r--r-- | core/java/android/view/View.java | 105 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 15 | ||||
-rw-r--r-- | core/java/android/view/WindowManager.java | 2 | ||||
-rw-r--r-- | core/java/android/view/WindowManagerPolicy.java | 11 | ||||
-rw-r--r-- | core/java/android/view/inputmethod/BaseInputConnection.java | 30 | ||||
-rw-r--r-- | core/java/android/view/inputmethod/InputConnection.java | 26 | ||||
-rw-r--r-- | core/java/android/view/inputmethod/InputMethodManager.java | 33 |
9 files changed, 217 insertions, 53 deletions
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java new file mode 100644 index 0000000..cc3563c --- /dev/null +++ b/core/java/android/view/HapticFeedbackConstants.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +/** + * Constants to be used to perform haptic feedback effects via + * {@link View#performHapticFeedback(int)} + */ +public class HapticFeedbackConstants { + + private HapticFeedbackConstants() {} + + public static final int LONG_PRESS = 0; + + /** @hide pending API council */ + public static final int ZOOM_RING_TICK = 1; + + /** + * Flag for {@link View#performHapticFeedback(int, int) + * View.performHapticFeedback(int, int)}: Ignore the setting in the + * view for whether to perform haptic feedback, do it always. + */ + public static final int FLAG_IGNORE_VIEW_SETTING = 0x0001; + + /** + * Flag for {@link View#performHapticFeedback(int, int) + * View.performHapticFeedback(int, int)}: Ignore the global setting + * for whether to perform haptic feedback, do it always. + */ + public static final int FLAG_IGNORE_GLOBAL_SETTING = 0x0002; +} diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 7276f17..1156856 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -106,5 +106,6 @@ interface IWindowSession { void setInTouchMode(boolean showFocus); boolean getInTouchMode(); + + boolean performHapticFeedback(IWindow window, int effectId, boolean always); } - diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index a51b564..1d5e7cd 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -836,6 +836,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback { public static final int SOUND_EFFECTS_ENABLED = 0x08000000; /** + * View flag indicating whether this view should have haptic feedback + * enabled for events such as long presses. + */ + public static final int HAPTIC_FEEDBACK_ENABLED = 0x10000000; + + /** * Use with {@link #focusSearch}. Move focus to the previous selectable * item. */ @@ -1637,6 +1643,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback { public View(Context context) { mContext = context; mResources = context != null ? context.getResources() : null; + mViewFlags = SOUND_EFFECTS_ENABLED|HAPTIC_FEEDBACK_ENABLED; ++sInstanceCount; } @@ -1703,9 +1710,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback { int scrollbarStyle = SCROLLBARS_INSIDE_OVERLAY; - viewFlagValues |= SOUND_EFFECTS_ENABLED; - viewFlagMasks |= SOUND_EFFECTS_ENABLED; - final int N = a.getIndexCount(); for (int i = 0; i < N; i++) { int attr = a.getIndex(i); @@ -1801,6 +1805,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback { viewFlagValues &= ~SOUND_EFFECTS_ENABLED; viewFlagMasks |= SOUND_EFFECTS_ENABLED; } + case com.android.internal.R.styleable.View_hapticFeedbackEnabled: + if (!a.getBoolean(attr, true)) { + viewFlagValues &= ~HAPTIC_FEEDBACK_ENABLED; + viewFlagMasks |= HAPTIC_FEEDBACK_ENABLED; + } case R.styleable.View_scrollbars: final int scrollbars = a.getInt(attr, SCROLLBARS_NONE); if (scrollbars != SCROLLBARS_NONE) { @@ -2182,6 +2191,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback { if (!handled) { handled = showContextMenu(); } + if (handled) { + performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + } return handled; } @@ -2742,7 +2754,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback { * Set whether this view should have sound effects enabled for events such as * clicking and touching. * - * You may wish to disable sound effects for a view if you already play sounds, + * <p>You may wish to disable sound effects for a view if you already play sounds, * for instance, a dial key that plays dtmf tones. * * @param soundEffectsEnabled whether sound effects are enabled for this view. @@ -2768,6 +2780,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback { } /** + * Set whether this view should have haptic feedback for events such as + * long presses. + * + * <p>You may wish to disable haptic feedback if your view already controls + * its own haptic feedback. + * + * @param hapticFeedbackEnabled whether haptic feedback enabled for this view. + * @see #isHapticFeedbackEnabled() + * @see #performHapticFeedback(int) + * @attr ref android.R.styleable#View_hapticFeedbackEnabled + */ + public void setHapticFeedbackEnabled(boolean hapticFeedbackEnabled) { + setFlags(hapticFeedbackEnabled ? HAPTIC_FEEDBACK_ENABLED: 0, HAPTIC_FEEDBACK_ENABLED); + } + + /** + * @return whether this view should have haptic feedback enabled for events + * long presses. + * + * @see #setHapticFeedbackEnabled(boolean) + * @see #performHapticFeedback(int) + * @attr ref android.R.styleable#View_hapticFeedbackEnabled + */ + @ViewDebug.ExportedProperty + public boolean isHapticFeedbackEnabled() { + return HAPTIC_FEEDBACK_ENABLED == (mViewFlags & HAPTIC_FEEDBACK_ENABLED); + } + + /** * If this view doesn't do any drawing on its own, set this flag to * allow further optimizations. By default, this flag is not set on * View, but could be set on some View subclasses such as ViewGroup. @@ -7312,20 +7353,57 @@ public class View implements Drawable.Callback, KeyEvent.Callback { /** * Play a sound effect for this view. * - * The framework will play sound effects for some built in actions, such as + * <p>The framework will play sound effects for some built in actions, such as * clicking, but you may wish to play these effects in your widget, * for instance, for internal navigation. * - * The sound effect will only be played if sound effects are enabled by the user, and + * <p>The sound effect will only be played if sound effects are enabled by the user, and * {@link #isSoundEffectsEnabled()} is true. * * @param soundConstant One of the constants defined in {@link SoundEffectConstants} */ - protected void playSoundEffect(int soundConstant) { - if (mAttachInfo == null || mAttachInfo.mSoundEffectPlayer == null || !isSoundEffectsEnabled()) { + public void playSoundEffect(int soundConstant) { + if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) { return; } - mAttachInfo.mSoundEffectPlayer.playSoundEffect(soundConstant); + mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant); + } + + /** + * Provide haptic feedback to the user for this view. + * + * <p>The framework will provide haptic feedback for some built in actions, + * such as long presses, but you may wish to provide feedback for your + * own widget. + * + * <p>The feedback will only be performed if + * {@link #isHapticFeedbackEnabled()} is true. + * + * @param feedbackConstant One of the constants defined in + * {@link HapticFeedbackConstants} + */ + public boolean performHapticFeedback(int feedbackConstant) { + return performHapticFeedback(feedbackConstant, 0); + } + + /** + * Like {@link #performHapticFeedback(int)}, with additional options. + * + * @param feedbackConstant One of the constants defined in + * {@link HapticFeedbackConstants} + * @param flags Additional flags as per {@link HapticFeedbackConstants}. + */ + public boolean performHapticFeedback(int feedbackConstant, int flags) { + if (mAttachInfo == null) { + return false; + } + if ((flags&HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0 + && !isHapticFeedbackEnabled()) { + return false; + } + return mAttachInfo.mRootCallbacks.performHapticFeedback( + feedbackConstant, + (flags&HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0); } /** @@ -7704,8 +7782,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback { */ static class AttachInfo { - interface SoundEffectPlayer { + interface Callbacks { void playSoundEffect(int effectId); + boolean performHapticFeedback(int effectId, boolean always); } /** @@ -7775,7 +7854,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback { final IBinder mWindowToken; - final SoundEffectPlayer mSoundEffectPlayer; + final Callbacks mRootCallbacks; /** * The top view of the hierarchy. @@ -7922,12 +8001,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback { * @param handler the events handler the view must use */ AttachInfo(IWindowSession session, IWindow window, - Handler handler, SoundEffectPlayer effectPlayer) { + Handler handler, Callbacks effectPlayer) { mSession = session; mWindow = window; mWindowToken = window.asBinder(); mHandler = handler; - mSoundEffectPlayer = effectPlayer; + mRootCallbacks = effectPlayer; } } diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 4e46397..ccfa6bf 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -61,7 +61,7 @@ import static javax.microedition.khronos.opengles.GL10.*; */ @SuppressWarnings({"EmptyCatchBlock"}) public final class ViewRoot extends Handler implements ViewParent, - View.AttachInfo.SoundEffectPlayer { + View.AttachInfo.Callbacks { private static final String TAG = "ViewRoot"; private static final boolean DBG = false; @SuppressWarnings({"ConstantConditionalExpression"}) @@ -1637,7 +1637,7 @@ public final class ViewRoot extends Handler implements ViewParent, dispatchDetachedFromWindow(); break; case DISPATCH_KEY_FROM_IME: - if (true) Log.v( + if (LOCAL_LOGV) Log.v( "ViewRoot", "Dispatching key " + msg.obj + " from IME to " + mView); deliverKeyEventToViewHierarchy((KeyEvent)msg.obj, false); @@ -2238,6 +2238,17 @@ public final class ViewRoot extends Handler implements ViewParent, /** * {@inheritDoc} */ + public boolean performHapticFeedback(int effectId, boolean always) { + try { + return sWindowSession.performHapticFeedback(mWindow, effectId, always); + } catch (RemoteException e) { + return false; + } + } + + /** + * {@inheritDoc} + */ public View focusSearch(View focused, int direction) { checkThread(); if (!(mView instanceof ViewGroup)) { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index d08a6fa..406af3e3 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -925,7 +925,7 @@ public interface WindowManager extends ViewManager { sb.append(Integer.toHexString(windowAnimations)); } if (screenOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { - sb.append("or="); + sb.append(" or="); sb.append(screenOrientation); } sb.append('}'); diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 542b35f..051f823 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -771,4 +771,15 @@ public interface WindowManagerPolicy { public boolean isCheekPressedAgainstScreen(MotionEvent ev); public void setCurrentOrientation(int newOrientation); + + /** + * Call from application to perform haptic feedback on its window. + */ + public boolean performHapticFeedback(WindowState win, int effectId, boolean always); + + /** + * Called when we have stopped keeping the screen on because a window + * requesting this is no longer visible. + */ + public void screenOnStopped(); } diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java index 56c6c92..9509b15 100644 --- a/core/java/android/view/inputmethod/BaseInputConnection.java +++ b/core/java/android/view/inputmethod/BaseInputConnection.java @@ -371,6 +371,14 @@ public class BaseInputConnection implements InputConnection { if (DEBUG) Log.v(TAG, "setSelection " + start + ", " + end); final Editable content = getEditable(); if (content == null) return false; + int len = content.length(); + if (start > len || end > len) { + // If the given selection is out of bounds, just ignore it. + // Most likely the text was changed out from under the IME, + // the the IME is going to have to update all of its state + // anyway. + return true; + } Selection.setSelection(content, start, end); return true; } @@ -396,20 +404,10 @@ public class BaseInputConnection implements InputConnection { } /** - * Provides standard implementation for hiding the status icon associated - * with the current input method. + * Updates InputMethodManager with the current fullscreen mode. */ - public boolean hideStatusIcon() { - mIMM.updateStatusIcon(0, null); - return true; - } - - /** - * Provides standard implementation for showing the status icon associated - * with the current input method. - */ - public boolean showStatusIcon(String packageName, int resId) { - mIMM.updateStatusIcon(resId, packageName); + public boolean reportFullscreenMode(boolean enabled) { + mIMM.setFullscreenMode(enabled); return true; } @@ -420,7 +418,11 @@ public class BaseInputConnection implements InputConnection { Editable content = getEditable(); if (content != null) { - if (content.length() == 1) { + final int N = content.length(); + if (N == 0) { + return; + } + if (N == 1) { // If it's 1 character, we have a chance of being // able to generate normal key events... if (mKeyCharacterMap == null) { diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java index 8c30d3f..13173f6 100644 --- a/core/java/android/view/inputmethod/InputConnection.java +++ b/core/java/android/view/inputmethod/InputConnection.java @@ -267,6 +267,13 @@ public interface InputConnection { public boolean clearMetaKeyStates(int states); /** + * Called by the IME to tell the client when it switches between fullscreen + * and normal modes. This will normally be called for you by the standard + * implementation of {@link android.inputmethodservice.InputMethodService}. + */ + public boolean reportFullscreenMode(boolean enabled); + + /** * API to send private commands from an input method to its connected * editor. This can be used to provide domain-specific features that are * only known between certain input methods and their clients. Note that @@ -284,23 +291,4 @@ public interface InputConnection { * valid. */ public boolean performPrivateCommand(String action, Bundle data); - - /** - * Show an icon in the status bar. - * - * @param packageName The package holding the icon resource to be shown. - * @param resId The resource id of the icon to show. - * - * @return Returns true on success, false if the input connection is no longer - * valid. - */ - public boolean showStatusIcon(String packageName, int resId); - - /** - * Hide the icon shown in the status bar. - * - * @return Returns true on success, false if the input connection is no longer - * valid. - */ - public boolean hideStatusIcon(); } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 99d5aa5..fe14166 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -214,6 +214,11 @@ public final class InputMethodManager { */ boolean mActive = false; + /** + * As reported by IME through InputConnection. + */ + boolean mFullscreenMode; + // ----------------------------------------------------------- /** @@ -374,6 +379,7 @@ public final class InputMethodManager { public void setActive(boolean active) { mActive = active; + mFullscreenMode = false; } }; @@ -443,14 +449,36 @@ public final class InputMethodManager { } } - public void updateStatusIcon(int iconId, String iconPackage) { + public void showStatusIcon(IBinder imeToken, String packageName, int iconId) { + try { + mService.updateStatusIcon(imeToken, packageName, iconId); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + public void hideStatusIcon(IBinder imeToken) { try { - mService.updateStatusIcon(iconId, iconPackage); + mService.updateStatusIcon(imeToken, null, 0); } catch (RemoteException e) { throw new RuntimeException(e); } } + /** @hide */ + public void setFullscreenMode(boolean enabled) { + mFullscreenMode = true; + } + + /** + * Allows you to discover whether the attached input method is running + * in fullscreen mode. Return true if it is fullscreen, entirely covering + * your UI, else returns false. + */ + public boolean isFullscreenMode() { + return mFullscreenMode; + } + /** * Return true if the given view is the currently active view for the * input method. @@ -503,7 +531,6 @@ public final class InputMethodManager { void finishInputLocked() { if (mServedView != null) { if (DEBUG) Log.v(TAG, "FINISH INPUT: " + mServedView); - updateStatusIcon(0, null); if (mCurrentTextBoxAttribute != null) { try { |