Merge "Introduce animated pointer icon for STYLE_WAIT."
@@ -24,6 +24,7 @@ import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Parcel;
|
||||
@@ -142,6 +143,10 @@ public final class PointerIcon implements Parcelable {
|
||||
private Bitmap mBitmap;
|
||||
private float mHotSpotX;
|
||||
private float mHotSpotY;
|
||||
// The bitmaps for the additional frame of animated pointer icon. Note that the first frame
|
||||
// will be stored in mBitmap.
|
||||
private Bitmap mBitmapFrames[];
|
||||
private int mDurationPerFrame;
|
||||
|
||||
private PointerIcon(int style) {
|
||||
mStyle = style;
|
||||
@@ -472,6 +477,36 @@ public final class PointerIcon implements Parcelable {
|
||||
} else {
|
||||
drawable = context.getDrawable(bitmapRes);
|
||||
}
|
||||
if (drawable instanceof AnimationDrawable) {
|
||||
// Extract animation frame bitmaps.
|
||||
final AnimationDrawable animationDrawable = (AnimationDrawable) drawable;
|
||||
final int frames = animationDrawable.getNumberOfFrames();
|
||||
drawable = animationDrawable.getFrame(0);
|
||||
if (frames == 1) {
|
||||
Log.w(TAG, "Animation icon with single frame -- simply treating the first "
|
||||
+ "frame as a normal bitmap icon.");
|
||||
} else {
|
||||
// Assumes they have the exact duration.
|
||||
mDurationPerFrame = animationDrawable.getDuration(0);
|
||||
mBitmapFrames = new Bitmap[frames - 1];
|
||||
final int width = drawable.getIntrinsicWidth();
|
||||
final int height = drawable.getIntrinsicHeight();
|
||||
for (int i = 1; i < frames; ++i) {
|
||||
Drawable drawableFrame = animationDrawable.getFrame(i);
|
||||
if (!(drawableFrame instanceof BitmapDrawable)) {
|
||||
throw new IllegalArgumentException("Frame of an animated pointer icon "
|
||||
+ "must refer to a bitmap drawable.");
|
||||
}
|
||||
if (drawableFrame.getIntrinsicWidth() != width ||
|
||||
drawableFrame.getIntrinsicHeight() != height) {
|
||||
throw new IllegalArgumentException("The bitmap size of " + i + "-th frame "
|
||||
+ "is different. All frames should have the exact same size and "
|
||||
+ "share the same hotspot.");
|
||||
}
|
||||
mBitmapFrames[i - 1] = ((BitmapDrawable)drawableFrame).getBitmap();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(drawable instanceof BitmapDrawable)) {
|
||||
throw new IllegalArgumentException("<pointer-icon> bitmap attribute must "
|
||||
+ "refer to a bitmap drawable.");
|
||||
@@ -509,8 +544,7 @@ public final class PointerIcon implements Parcelable {
|
||||
case STYLE_HELP:
|
||||
return com.android.internal.R.styleable.Pointer_pointerIconHelp;
|
||||
case STYLE_WAIT:
|
||||
// falls back to the default icon because no animation support.
|
||||
return com.android.internal.R.styleable.Pointer_pointerIconArrow;
|
||||
return com.android.internal.R.styleable.Pointer_pointerIconWait;
|
||||
case STYLE_CELL:
|
||||
return com.android.internal.R.styleable.Pointer_pointerIconCell;
|
||||
case STYLE_CROSSHAIR:
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <android_runtime/Log.h>
|
||||
#include <utils/Log.h>
|
||||
#include <android/graphics/GraphicsJNI.h>
|
||||
#include "ScopedLocalRef.h"
|
||||
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
@@ -35,6 +36,8 @@ static struct {
|
||||
jfieldID mBitmap;
|
||||
jfieldID mHotSpotX;
|
||||
jfieldID mHotSpotY;
|
||||
jfieldID mBitmapFrames;
|
||||
jfieldID mDurationPerFrame;
|
||||
jmethodID getSystemIcon;
|
||||
jmethodID load;
|
||||
} gPointerIconClassInfo;
|
||||
@@ -84,6 +87,19 @@ status_t android_view_PointerIcon_load(JNIEnv* env, jobject pointerIconObj, jobj
|
||||
env->DeleteLocalRef(bitmapObj);
|
||||
}
|
||||
|
||||
ScopedLocalRef<jobjectArray> bitmapFramesObj(env, reinterpret_cast<jobjectArray>(
|
||||
env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmapFrames)));
|
||||
if (bitmapFramesObj.get()) {
|
||||
outPointerIcon->durationPerFrame = env->GetIntField(
|
||||
loadedPointerIconObj, gPointerIconClassInfo.mDurationPerFrame);
|
||||
jsize size = env->GetArrayLength(bitmapFramesObj.get());
|
||||
outPointerIcon->bitmapFrames.resize(size);
|
||||
for (jsize i = 0; i < size; ++i) {
|
||||
ScopedLocalRef<jobject> bitmapObj(env, env->GetObjectArrayElement(bitmapFramesObj.get(), i));
|
||||
GraphicsJNI::getSkBitmap(env, bitmapObj.get(), &(outPointerIcon->bitmapFrames[i]));
|
||||
}
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(loadedPointerIconObj);
|
||||
return OK;
|
||||
}
|
||||
@@ -121,6 +137,12 @@ int register_android_view_PointerIcon(JNIEnv* env) {
|
||||
gPointerIconClassInfo.mHotSpotY = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
|
||||
"mHotSpotY", "F");
|
||||
|
||||
gPointerIconClassInfo.mBitmapFrames = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
|
||||
"mBitmapFrames", "[Landroid/graphics/Bitmap;");
|
||||
|
||||
gPointerIconClassInfo.mDurationPerFrame = GetFieldIDOrDie(env, gPointerIconClassInfo.clazz,
|
||||
"mDurationPerFrame", "I");
|
||||
|
||||
gPointerIconClassInfo.getSystemIcon = GetStaticMethodIDOrDie(env, gPointerIconClassInfo.clazz,
|
||||
"getSystemIcon", "(Landroid/content/Context;I)Landroid/view/PointerIcon;");
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "jni.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <SkBitmap.h>
|
||||
|
||||
@@ -69,6 +71,8 @@ struct PointerIcon {
|
||||
SkBitmap bitmap;
|
||||
float hotSpotX;
|
||||
float hotSpotY;
|
||||
std::vector<SkBitmap> bitmapFrames;
|
||||
int32_t durationPerFrame;
|
||||
|
||||
inline bool isNullIcon() {
|
||||
return style == POINTER_ICON_STYLE_NULL;
|
||||
@@ -79,6 +83,8 @@ struct PointerIcon {
|
||||
bitmap.reset();
|
||||
hotSpotX = 0;
|
||||
hotSpotY = 0;
|
||||
bitmapFrames.clear();
|
||||
durationPerFrame = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BIN
core/res/res/drawable-mdpi/pointer_wait_0.png
Normal file
|
After Width: | Height: | Size: 606 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_1.png
Normal file
|
After Width: | Height: | Size: 603 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_10.png
Normal file
|
After Width: | Height: | Size: 619 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_11.png
Normal file
|
After Width: | Height: | Size: 605 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_12.png
Normal file
|
After Width: | Height: | Size: 617 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_13.png
Normal file
|
After Width: | Height: | Size: 626 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_14.png
Normal file
|
After Width: | Height: | Size: 629 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_15.png
Normal file
|
After Width: | Height: | Size: 623 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_16.png
Normal file
|
After Width: | Height: | Size: 610 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_17.png
Normal file
|
After Width: | Height: | Size: 594 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_18.png
Normal file
|
After Width: | Height: | Size: 652 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_19.png
Normal file
|
After Width: | Height: | Size: 616 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_2.png
Normal file
|
After Width: | Height: | Size: 635 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_20.png
Normal file
|
After Width: | Height: | Size: 623 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_21.png
Normal file
|
After Width: | Height: | Size: 675 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_22.png
Normal file
|
After Width: | Height: | Size: 699 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_23.png
Normal file
|
After Width: | Height: | Size: 708 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_24.png
Normal file
|
After Width: | Height: | Size: 687 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_25.png
Normal file
|
After Width: | Height: | Size: 697 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_26.png
Normal file
|
After Width: | Height: | Size: 668 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_27.png
Normal file
|
After Width: | Height: | Size: 678 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_28.png
Normal file
|
After Width: | Height: | Size: 668 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_29.png
Normal file
|
After Width: | Height: | Size: 650 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_3.png
Normal file
|
After Width: | Height: | Size: 657 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_30.png
Normal file
|
After Width: | Height: | Size: 674 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_31.png
Normal file
|
After Width: | Height: | Size: 653 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_32.png
Normal file
|
After Width: | Height: | Size: 654 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_33.png
Normal file
|
After Width: | Height: | Size: 629 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_34.png
Normal file
|
After Width: | Height: | Size: 638 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_35.png
Normal file
|
After Width: | Height: | Size: 608 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_4.png
Normal file
|
After Width: | Height: | Size: 670 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_5.png
Normal file
|
After Width: | Height: | Size: 639 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_6.png
Normal file
|
After Width: | Height: | Size: 603 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_7.png
Normal file
|
After Width: | Height: | Size: 623 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_8.png
Normal file
|
After Width: | Height: | Size: 609 B |
BIN
core/res/res/drawable-mdpi/pointer_wait_9.png
Normal file
|
After Width: | Height: | Size: 634 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_0.png
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_1.png
Normal file
|
After Width: | Height: | Size: 1017 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_10.png
Normal file
|
After Width: | Height: | Size: 954 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_11.png
Normal file
|
After Width: | Height: | Size: 989 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_12.png
Normal file
|
After Width: | Height: | Size: 964 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_13.png
Normal file
|
After Width: | Height: | Size: 1012 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_14.png
Normal file
|
After Width: | Height: | Size: 977 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_15.png
Normal file
|
After Width: | Height: | Size: 984 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_16.png
Normal file
|
After Width: | Height: | Size: 945 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_17.png
Normal file
|
After Width: | Height: | Size: 956 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_18.png
Normal file
|
After Width: | Height: | Size: 1010 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_19.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_2.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_20.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_21.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_22.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_23.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_24.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_25.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_26.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_27.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_28.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_29.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_3.png
Normal file
|
After Width: | Height: | Size: 1006 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_30.png
Normal file
|
After Width: | Height: | Size: 1015 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_31.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_32.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
core/res/res/drawable-xhdpi/pointer_wait_33.png
Normal file
|
After Width: | Height: | Size: 1005 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_34.png
Normal file
|
After Width: | Height: | Size: 974 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_35.png
Normal file
|
After Width: | Height: | Size: 965 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_4.png
Normal file
|
After Width: | Height: | Size: 1015 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_5.png
Normal file
|
After Width: | Height: | Size: 1009 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_6.png
Normal file
|
After Width: | Height: | Size: 1002 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_7.png
Normal file
|
After Width: | Height: | Size: 986 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_8.png
Normal file
|
After Width: | Height: | Size: 953 B |
BIN
core/res/res/drawable-xhdpi/pointer_wait_9.png
Normal file
|
After Width: | Height: | Size: 937 B |
38
core/res/res/drawable/pointer_wait.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
|
||||
<item android:drawable="@drawable/pointer_wait_1" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_2" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_3" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_4" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_5" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_6" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_7" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_8" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_9" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_10" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_11" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_12" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_13" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_14" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_15" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_16" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_17" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_18" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_19" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_20" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_21" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_22" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_23" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_24" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_25" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_26" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_27" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_28" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_29" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_30" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_31" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_32" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_33" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_34" android:duration="25"/>
|
||||
<item android:drawable="@drawable/pointer_wait_35" android:duration="25"/>
|
||||
</animation-list>
|
||||
5
core/res/res/drawable/pointer_wait_icon.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:bitmap="@drawable/pointer_wait"
|
||||
android:hotSpotX="7dp"
|
||||
android:hotSpotY="7dp" />
|
||||
@@ -7631,6 +7631,8 @@ i
|
||||
<attr name="pointerIconHand" format="reference"/>
|
||||
<!-- Reference to a pointer drawable with STYLE_HELP -->
|
||||
<attr name="pointerIconHelp" format="reference"/>
|
||||
<!-- Reference to a pointer drawable with STYLE_WAIT -->
|
||||
<attr name="pointerIconWait" format="reference"/>
|
||||
<!-- Reference to a pointer drawable with STYLE_CELL -->
|
||||
<attr name="pointerIconCell" format="reference"/>
|
||||
<!-- Reference to a pointer drawable with STYLE_CROSSHAIR -->
|
||||
|
||||
@@ -1339,6 +1339,7 @@ please see styles_device_defaults.xml.
|
||||
<item name="pointerIconHand">@drawable/pointer_hand_icon</item>
|
||||
<item name="pointerIconContextMenu">@drawable/pointer_context_menu_icon</item>
|
||||
<item name="pointerIconHelp">@drawable/pointer_help_icon</item>
|
||||
<item name="pointerIconWait">@drawable/pointer_wait_icon</item>
|
||||
<item name="pointerIconCell">@drawable/pointer_cell_icon</item>
|
||||
<item name="pointerIconCrosshair">@drawable/pointer_crosshair_icon</item>
|
||||
<item name="pointerIconText">@drawable/pointer_text_icon</item>
|
||||
|
||||
@@ -86,6 +86,9 @@ PointerController::PointerController(const sp<PointerControllerPolicyInterface>&
|
||||
mLocked.pointerIconChanged = false;
|
||||
mLocked.requestedPointerShape = mPolicy->getDefaultPointerIconId();
|
||||
|
||||
mLocked.animationFrameIndex = 0;
|
||||
mLocked.lastFrameUpdatedTime = 0;
|
||||
|
||||
mLocked.buttonState = 0;
|
||||
|
||||
loadResources();
|
||||
@@ -239,7 +242,8 @@ void PointerController::setPresentation(Presentation presentation) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
if (presentation == PRESENTATION_POINTER && mLocked.additionalMouseResources.empty()) {
|
||||
mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources);
|
||||
mPolicy->loadAdditionalMouseResources(&mLocked.additionalMouseResources,
|
||||
&mLocked.animationResources);
|
||||
}
|
||||
|
||||
if (mLocked.presentation != presentation) {
|
||||
@@ -402,7 +406,7 @@ void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_
|
||||
updatePointerLocked();
|
||||
}
|
||||
|
||||
void PointerController::updatePointerShape(int iconId) {
|
||||
void PointerController::updatePointerShape(int32_t iconId) {
|
||||
AutoMutex _l(mLock);
|
||||
if (mLocked.requestedPointerShape != iconId) {
|
||||
mLocked.requestedPointerShape = iconId;
|
||||
@@ -462,8 +466,17 @@ int PointerController::handleEvent(int /* fd */, int events, void* /* data */) {
|
||||
void PointerController::doAnimate(nsecs_t timestamp) {
|
||||
AutoMutex _l(mLock);
|
||||
|
||||
bool keepAnimating = false;
|
||||
mLocked.animationPending = false;
|
||||
|
||||
bool keepFading = doFadingAnimationLocked(timestamp);
|
||||
bool keepBitmapFlipping = doBitmapAnimationLocked(timestamp);
|
||||
if (keepFading || keepBitmapFlipping) {
|
||||
startAnimationLocked();
|
||||
}
|
||||
}
|
||||
|
||||
bool PointerController::doFadingAnimationLocked(nsecs_t timestamp) {
|
||||
bool keepAnimating = false;
|
||||
nsecs_t frameDelay = timestamp - mLocked.animationTime;
|
||||
|
||||
// Animate pointer fade.
|
||||
@@ -501,10 +514,32 @@ void PointerController::doAnimate(nsecs_t timestamp) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return keepAnimating;
|
||||
}
|
||||
|
||||
if (keepAnimating) {
|
||||
startAnimationLocked();
|
||||
bool PointerController::doBitmapAnimationLocked(nsecs_t timestamp) {
|
||||
std::map<int32_t, PointerAnimation>::const_iterator iter = mLocked.animationResources.find(
|
||||
mLocked.requestedPointerShape);
|
||||
if (iter == mLocked.animationResources.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timestamp - mLocked.lastFrameUpdatedTime > iter->second.durationPerFrame) {
|
||||
mSpriteController->openTransaction();
|
||||
|
||||
int incr = (timestamp - mLocked.lastFrameUpdatedTime) / iter->second.durationPerFrame;
|
||||
mLocked.animationFrameIndex += incr;
|
||||
mLocked.lastFrameUpdatedTime += iter->second.durationPerFrame * incr;
|
||||
while (mLocked.animationFrameIndex >= iter->second.animationFrames.size()) {
|
||||
mLocked.animationFrameIndex -= iter->second.animationFrames.size();
|
||||
}
|
||||
mLocked.pointerSprite->setIcon(iter->second.animationFrames[mLocked.animationFrameIndex]);
|
||||
|
||||
mSpriteController->closeTransaction();
|
||||
}
|
||||
|
||||
// Keep animating.
|
||||
return true;
|
||||
}
|
||||
|
||||
void PointerController::doInactivityTimeout() {
|
||||
@@ -549,9 +584,16 @@ void PointerController::updatePointerLocked() {
|
||||
if (mLocked.requestedPointerShape == mPolicy->getDefaultPointerIconId()) {
|
||||
mLocked.pointerSprite->setIcon(mLocked.pointerIcon);
|
||||
} else {
|
||||
std::map<int, SpriteIcon>::const_iterator iter =
|
||||
std::map<int32_t, SpriteIcon>::const_iterator iter =
|
||||
mLocked.additionalMouseResources.find(mLocked.requestedPointerShape);
|
||||
if (iter != mLocked.additionalMouseResources.end()) {
|
||||
std::map<int32_t, PointerAnimation>::const_iterator anim_iter =
|
||||
mLocked.animationResources.find(mLocked.requestedPointerShape);
|
||||
if (anim_iter != mLocked.animationResources.end()) {
|
||||
mLocked.animationFrameIndex = 0;
|
||||
mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
startAnimationLocked();
|
||||
}
|
||||
mLocked.pointerSprite->setIcon(iter->second);
|
||||
} else {
|
||||
ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerShape);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "SpriteController.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <ui/DisplayInfo.h>
|
||||
#include <input/Input.h>
|
||||
@@ -30,8 +31,6 @@
|
||||
#include <utils/String8.h>
|
||||
#include <gui/DisplayEventReceiver.h>
|
||||
|
||||
#include <SkBitmap.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
@@ -43,6 +42,11 @@ struct PointerResources {
|
||||
SpriteIcon spotAnchor;
|
||||
};
|
||||
|
||||
struct PointerAnimation {
|
||||
std::vector<SpriteIcon> animationFrames;
|
||||
nsecs_t durationPerFrame;
|
||||
};
|
||||
|
||||
/*
|
||||
* Pointer controller policy interface.
|
||||
*
|
||||
@@ -59,7 +63,8 @@ protected:
|
||||
|
||||
public:
|
||||
virtual void loadPointerResources(PointerResources* outResources) = 0;
|
||||
virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources) = 0;
|
||||
virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
|
||||
std::map<int32_t, PointerAnimation>* outAnimationResources) = 0;
|
||||
virtual int32_t getDefaultPointerIconId() = 0;
|
||||
};
|
||||
|
||||
@@ -98,7 +103,7 @@ public:
|
||||
const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
|
||||
virtual void clearSpots();
|
||||
|
||||
void updatePointerShape(int iconId);
|
||||
void updatePointerShape(int32_t iconId);
|
||||
void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
|
||||
void setPointerIcon(const SpriteIcon& icon);
|
||||
void setInactivityTimeout(InactivityTimeout inactivityTimeout);
|
||||
@@ -145,6 +150,9 @@ private:
|
||||
bool animationPending;
|
||||
nsecs_t animationTime;
|
||||
|
||||
size_t animationFrameIndex;
|
||||
nsecs_t lastFrameUpdatedTime;
|
||||
|
||||
int32_t displayWidth;
|
||||
int32_t displayHeight;
|
||||
int32_t displayOrientation;
|
||||
@@ -162,7 +170,8 @@ private:
|
||||
SpriteIcon pointerIcon;
|
||||
bool pointerIconChanged;
|
||||
|
||||
std::map<int, SpriteIcon> additionalMouseResources;
|
||||
std::map<int32_t, SpriteIcon> additionalMouseResources;
|
||||
std::map<int32_t, PointerAnimation> animationResources;
|
||||
|
||||
int32_t requestedPointerShape;
|
||||
|
||||
@@ -178,6 +187,8 @@ private:
|
||||
void handleMessage(const Message& message);
|
||||
int handleEvent(int fd, int events, void* data);
|
||||
void doAnimate(nsecs_t timestamp);
|
||||
bool doFadingAnimationLocked(nsecs_t timestamp);
|
||||
bool doBitmapAnimationLocked(nsecs_t timestamp);
|
||||
void doInactivityTimeout();
|
||||
|
||||
void startAnimationLocked();
|
||||
|
||||
@@ -152,18 +152,23 @@ static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
|
||||
getInputWindowHandleObjLocalRef(env);
|
||||
}
|
||||
|
||||
static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
|
||||
SpriteIcon* outSpriteIcon) {
|
||||
PointerIcon pointerIcon;
|
||||
static void loadSystemIconAsSpriteWithPointerIcon(JNIEnv* env, jobject contextObj, int32_t style,
|
||||
PointerIcon* outPointerIcon, SpriteIcon* outSpriteIcon) {
|
||||
status_t status = android_view_PointerIcon_loadSystemIcon(env,
|
||||
contextObj, style, &pointerIcon);
|
||||
contextObj, style, outPointerIcon);
|
||||
if (!status) {
|
||||
pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType);
|
||||
outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
|
||||
outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
|
||||
outPointerIcon->bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType);
|
||||
outSpriteIcon->hotSpotX = outPointerIcon->hotSpotX;
|
||||
outSpriteIcon->hotSpotY = outPointerIcon->hotSpotY;
|
||||
}
|
||||
}
|
||||
|
||||
static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
|
||||
SpriteIcon* outSpriteIcon) {
|
||||
PointerIcon pointerIcon;
|
||||
loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon);
|
||||
}
|
||||
|
||||
enum {
|
||||
WM_ACTION_PASS_TO_USER = 1,
|
||||
};
|
||||
@@ -238,7 +243,8 @@ public:
|
||||
/* --- PointerControllerPolicyInterface implementation --- */
|
||||
|
||||
virtual void loadPointerResources(PointerResources* outResources);
|
||||
virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources);
|
||||
virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
|
||||
std::map<int32_t, PointerAnimation>* outAnimationResources);
|
||||
virtual int32_t getDefaultPointerIconId();
|
||||
|
||||
private:
|
||||
@@ -1041,14 +1047,31 @@ void NativeInputManager::loadPointerResources(PointerResources* outResources) {
|
||||
&outResources->spotAnchor);
|
||||
}
|
||||
|
||||
void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources) {
|
||||
void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
|
||||
std::map<int32_t, PointerAnimation>* outAnimationResources) {
|
||||
JNIEnv* env = jniEnv();
|
||||
|
||||
for (int iconId = POINTER_ICON_STYLE_CONTEXT_MENU; iconId <= POINTER_ICON_STYLE_GRABBING;
|
||||
++iconId) {
|
||||
loadSystemIconAsSprite(env, mContextObj, iconId, &((*outResources)[iconId]));
|
||||
PointerIcon pointerIcon;
|
||||
loadSystemIconAsSpriteWithPointerIcon(
|
||||
env, mContextObj, iconId, &pointerIcon, &((*outResources)[iconId]));
|
||||
if (!pointerIcon.bitmapFrames.empty()) {
|
||||
PointerAnimation& animationData = (*outAnimationResources)[iconId];
|
||||
size_t numFrames = pointerIcon.bitmapFrames.size() + 1;
|
||||
animationData.durationPerFrame =
|
||||
milliseconds_to_nanoseconds(pointerIcon.durationPerFrame);
|
||||
animationData.animationFrames.reserve(numFrames);
|
||||
animationData.animationFrames.push_back(SpriteIcon(
|
||||
pointerIcon.bitmap, pointerIcon.hotSpotX, pointerIcon.hotSpotY));
|
||||
for (size_t i = 0; i < numFrames - 1; ++i) {
|
||||
animationData.animationFrames.push_back(SpriteIcon(
|
||||
pointerIcon.bitmapFrames[i], pointerIcon.hotSpotX, pointerIcon.hotSpotY));
|
||||
}
|
||||
}
|
||||
}
|
||||
loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_NULL, &((*outResources)[POINTER_ICON_STYLE_NULL]));
|
||||
loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_NULL,
|
||||
&((*outResources)[POINTER_ICON_STYLE_NULL]));
|
||||
}
|
||||
|
||||
int32_t NativeInputManager::getDefaultPointerIconId() {
|
||||
|
||||