1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
package org.robolectric.shadows;
import static android.os.Build.VERSION_CODES.M;
import static org.robolectric.util.reflector.Reflector.reflector;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.drawable.Icon.OnDrawableLoadedListener;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import java.util.concurrent.Executor;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.util.reflector.Direct;
import org.robolectric.util.reflector.ForType;
@SuppressWarnings({"UnusedDeclaration"})
@Implements(value = Icon.class, minSdk = M)
public class ShadowIcon {
@Nullable private static Executor executorOverride;
/** Set the executor where async drawable loading will run. */
public static void overrideExecutor(Executor executor) {
executorOverride = executor;
}
@RealObject private Icon realIcon;
@HiddenApi
@Implementation
public int getType() {
return reflector(IconReflector.class, realIcon).getType();
}
@HiddenApi
@Implementation
public int getResId() {
return reflector(IconReflector.class, realIcon).getResId();
}
@HiddenApi
@Implementation
public Bitmap getBitmap() {
return reflector(IconReflector.class, realIcon).getBitmap();
}
@HiddenApi
@Implementation
public Uri getUri() {
return reflector(IconReflector.class, realIcon).getUri();
}
@HiddenApi
@Implementation
public int getDataLength() {
return reflector(IconReflector.class, realIcon).getDataLength();
}
@HiddenApi
@Implementation
public int getDataOffset() {
return reflector(IconReflector.class, realIcon).getDataOffset();
}
@HiddenApi
@Implementation
public byte[] getDataBytes() {
return reflector(IconReflector.class, realIcon).getDataBytes();
}
@Implementation
protected void loadDrawableAsync(Context context, Message andThen) {
if (executorOverride != null) {
executorOverride.execute(
() -> {
andThen.obj = realIcon.loadDrawable(context);
andThen.sendToTarget();
});
} else {
reflector(IconReflector.class, realIcon).loadDrawableAsync(context, andThen);
}
}
@Implementation
protected void loadDrawableAsync(
Context context, final OnDrawableLoadedListener listener, Handler handler) {
if (executorOverride != null) {
executorOverride.execute(
() -> {
Drawable result = realIcon.loadDrawable(context);
handler.post(() -> listener.onDrawableLoaded(result));
});
} else {
reflector(IconReflector.class, realIcon).loadDrawableAsync(context, listener, handler);
}
}
@ForType(Icon.class)
interface IconReflector {
@Direct
int getType();
@Direct
int getResId();
@Direct
Bitmap getBitmap();
@Direct
Uri getUri();
@Direct
int getDataLength();
@Direct
int getDataOffset();
@Direct
byte[] getDataBytes();
@Direct
void loadDrawableAsync(Context context, Message andThen);
@Direct
void loadDrawableAsync(
Context context, final OnDrawableLoadedListener listener, Handler handler);
}
}
|