aboutsummaryrefslogtreecommitdiff
path: root/shadows/framework/src/main/java/org/robolectric/shadows/ShadowIcon.java
blob: 72aa2fe321f1a25fd36007a8e5e12057400d1756 (plain)
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.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 androidx.annotation.Nullable;
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);
  }
}