Home | History | Annotate | Download | only in shadows
      1 package com.xtremelabs.robolectric.shadows;
      2 
      3 import android.content.ComponentName;
      4 import android.content.Context;
      5 import android.content.Intent;
      6 import android.net.Uri;
      7 import android.os.Bundle;
      8 import android.os.Parcel;
      9 import android.os.Parcelable;
     10 import android.os.Parcelable.Creator;
     11 
     12 import com.xtremelabs.robolectric.Robolectric;
     13 import com.xtremelabs.robolectric.internal.Implementation;
     14 import com.xtremelabs.robolectric.internal.Implements;
     15 import com.xtremelabs.robolectric.internal.RealObject;
     16 import com.xtremelabs.robolectric.util.Join;
     17 
     18 import java.io.*;
     19 import java.util.*;
     20 
     21 import static android.content.Intent.*;
     22 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
     23 
     24 @SuppressWarnings({"UnusedDeclaration"})
     25 @Implements(Intent.class)
     26 public class ShadowIntent {
     27     @RealObject private Intent realIntent;
     28 
     29     private final Bundle extras = new Bundle();
     30     private String action;
     31     private ComponentName componentName;
     32     private String type;
     33     private Uri data;
     34     private int flags;
     35     private Class<?> intentClass;
     36     private String packageName;
     37     private final Set<String> categories = new HashSet<String>();
     38 
     39     public void __constructor__(Context packageContext, Class cls) {
     40         componentName = new ComponentName(packageContext, cls);
     41         intentClass = cls;
     42     }
     43 
     44     public void __constructor__(String action, Uri uri) {
     45         this.action = action;
     46         data = uri;
     47     }
     48 
     49     public void __constructor__(String action) {
     50         __constructor__(action, null);
     51     }
     52 
     53     public void __constructor__(Intent intent) {
     54         ShadowIntent other = shadowOf(intent);
     55         extras.putAll(other.extras);
     56         action = other.action;
     57         componentName = other.componentName;
     58         type = other.type;
     59         data = other.data;
     60         flags = other.flags;
     61         intentClass = other.intentClass;
     62         packageName = other.packageName;
     63         categories.addAll(other.categories);
     64     }
     65 
     66     @Implementation
     67     public static Intent createChooser(Intent target, CharSequence title) {
     68         Intent intent = new Intent(Intent.ACTION_CHOOSER);
     69         intent.putExtra(Intent.EXTRA_INTENT, target);
     70         if (title != null) {
     71             intent.putExtra(Intent.EXTRA_TITLE, title);
     72         }
     73         return intent;
     74     }
     75 
     76     @Implementation
     77     public Intent setAction(String action) {
     78         this.action = action;
     79         return realIntent;
     80     }
     81 
     82     @Implementation
     83     public String getAction() {
     84         return action;
     85     }
     86 
     87     @Implementation
     88     public Intent setType(String type) {
     89         this.type = type;
     90         this.data = null;
     91         return realIntent;
     92     }
     93 
     94     @Implementation
     95     public Intent setDataAndType(Uri data, String type) {
     96         this.data = data;
     97         this.type = type;
     98         return realIntent;
     99     }
    100 
    101     @Implementation
    102     public String getType() {
    103         return type;
    104     }
    105 
    106     @Implementation
    107     public Intent addCategory(String category) {
    108         categories.add(category);
    109         return realIntent;
    110     }
    111 
    112     @Implementation
    113     public void removeCategory(String category) {
    114         categories.remove(category);
    115     }
    116 
    117     @Implementation
    118     public boolean hasCategory(String category) {
    119         return categories.contains(category);
    120     }
    121 
    122     @Implementation
    123     public Set<String> getCategories() {
    124         return categories;
    125     }
    126 
    127     @Implementation
    128     public Intent setPackage(String packageName) {
    129         this.packageName = packageName;
    130         return realIntent;
    131     }
    132 
    133     @Implementation
    134     public String getPackage() {
    135         return packageName;
    136     }
    137 
    138     @Implementation
    139     public Uri getData() {
    140         return data;
    141     }
    142 
    143     @Implementation
    144     public Intent setClass(Context packageContext, Class<?> cls) {
    145         this.intentClass = cls;
    146         return realIntent;
    147     }
    148 
    149     @Implementation
    150     public Intent setClassName(String packageName, String className) {
    151         componentName = new ComponentName(packageName, className);
    152         try {
    153             this.intentClass = Class.forName(className);
    154         } catch (ClassNotFoundException e) {
    155             // ignore
    156         }
    157         return realIntent;
    158     }
    159 
    160     @Implementation
    161     public Intent setClassName(Context packageContext, String className) {
    162         componentName = new ComponentName(packageContext.getPackageName(), className);
    163         return realIntent;
    164     }
    165 
    166     @Implementation
    167     public Intent setData(Uri data) {
    168         this.data = data;
    169         this.type = null;
    170         return realIntent;
    171     }
    172 
    173     @Implementation
    174     public int getFlags() {
    175         return flags;
    176     }
    177 
    178     @Implementation
    179     public Intent setFlags(int flags) {
    180         this.flags = flags;
    181         return realIntent;
    182     }
    183 
    184     @Implementation
    185     public Intent addFlags(int flags) {
    186         this.flags |= flags;
    187         return realIntent;
    188     }
    189 
    190     @Implementation
    191     public Intent putExtras(Bundle src) {
    192         extras.putAll(src);
    193         return realIntent;
    194     }
    195 
    196     @Implementation
    197     public Intent putExtras(Intent src) {
    198         ShadowIntent srcShadowIntent = shadowOf(src);
    199         extras.putAll(srcShadowIntent.extras);
    200         return realIntent;
    201     }
    202 
    203     @Implementation
    204     public Bundle getExtras() {
    205         return extras != null ? new Bundle(extras) : null;
    206     }
    207 
    208     @Implementation
    209     public Intent putExtra(String key, int value) {
    210         extras.putInt(key, value);
    211         return realIntent;
    212     }
    213 
    214     @Implementation
    215     public Intent putExtra(String key, double value) {
    216         extras.putDouble(key, value);
    217         return realIntent;
    218     }
    219 
    220     @Implementation
    221     public Intent putExtra(String key, float value) {
    222         extras.putFloat(key, value);
    223         return realIntent;
    224     }
    225 
    226     @Implementation
    227     public Intent putExtra(String key, long value) {
    228         extras.putLong(key, value);
    229         return realIntent;
    230     }
    231 
    232     @Implementation
    233     public Intent putExtra(String key, Serializable value) {
    234         extras.putSerializable(key, serializeCycle(value));
    235         return realIntent;
    236     }
    237 
    238     @Implementation
    239     public Intent putExtra(String key, Parcelable value) {
    240         extras.putParcelable(key, value);
    241         return realIntent;
    242     }
    243 
    244     @Implementation
    245     public Intent putExtra(String key, Parcelable[] value) {
    246         extras.putParcelableArray(key, value);
    247         return realIntent;
    248     }
    249 
    250     @Implementation
    251     public Intent putExtra(String key, String value) {
    252         extras.putString(key, value);
    253         return realIntent;
    254     }
    255 
    256     @Implementation
    257     public Intent putExtra(String key, String[] value) {
    258         extras.putStringArray(key, value);
    259         return realIntent;
    260     }
    261 
    262     @Implementation
    263     public Intent putExtra(String key, Bundle value) {
    264         extras.putBundle(key, value);
    265         return realIntent;
    266     }
    267 
    268     @Implementation
    269     public Intent putExtra(String key, boolean value) {
    270         extras.putBoolean(key, value);
    271         return realIntent;
    272     }
    273 
    274     @Implementation
    275     public Intent putExtra(String key, int[] value) {
    276         extras.putIntArray(key, value);
    277         return realIntent;
    278     }
    279 
    280     @Implementation
    281     public Intent putExtra(String key, long[] value) {
    282         extras.putLongArray(key, value);
    283         return realIntent;
    284     }
    285 
    286     @Implementation
    287     public int[] getIntArrayExtra(String name) {
    288         return extras.getIntArray(name);
    289     }
    290 
    291     @Implementation
    292     public long[] getLongArrayExtra(String name) {
    293         return extras.getLongArray(name);
    294     }
    295 
    296     @Implementation
    297     public boolean getBooleanExtra(String name, boolean defaultValue) {
    298         return extras.getBoolean(name, defaultValue);
    299     }
    300 
    301     @Implementation
    302     public String[] getStringArrayExtra(String name) {
    303         return extras.getStringArray(name);
    304     }
    305 
    306     @Implementation
    307     public Intent putExtra(String key, CharSequence value) {
    308         extras.putCharSequence(key, value);
    309         return realIntent;
    310     }
    311 
    312     @Implementation
    313     public CharSequence getCharSequenceExtra(String name) {
    314         return extras.getCharSequence(name);
    315     }
    316 
    317     @Implementation
    318     public void putExtra(String key, byte[] value) {
    319         extras.putByteArray(key, value);
    320     }
    321 
    322     @Implementation
    323     public Intent putStringArrayListExtra(String key, ArrayList<String> value) {
    324         extras.putStringArrayList(key, value);
    325         return realIntent;
    326     }
    327 
    328     @Implementation
    329     public ArrayList<String> getStringArrayListExtra(String name) {
    330         return extras.getStringArrayList(name);
    331     }
    332 
    333     @Implementation
    334     public Intent putIntegerArrayListExtra(String key, ArrayList<Integer> value) {
    335         extras.putIntegerArrayList(key, value);
    336         return realIntent;
    337     }
    338 
    339     @Implementation
    340     public ArrayList<Integer> getIntegerArrayListExtra(String name) {
    341         return extras.getIntegerArrayList(name);
    342     }
    343 
    344     @Implementation
    345     public Intent putParcelableArrayListExtra(String key, ArrayList<Parcelable> value) {
    346         extras.putParcelableArrayList(key, value);
    347         return realIntent;
    348     }
    349 
    350     @Implementation
    351     public ArrayList<Parcelable> getParcelableArrayListExtra(String key) {
    352         return extras.getParcelableArrayList(key);
    353     }
    354 
    355     @Implementation
    356     public boolean hasExtra(String name) {
    357         return extras.containsKey(name);
    358     }
    359 
    360     @Implementation
    361     public String getStringExtra(String name) {
    362         return extras.getString(name);
    363     }
    364 
    365     @Implementation
    366     public Parcelable getParcelableExtra(String name) {
    367         return extras.getParcelable(name);
    368     }
    369 
    370     @Implementation
    371     public Parcelable[] getParcelableArrayExtra(String name) {
    372         return extras.getParcelableArray(name);
    373     }
    374 
    375     @Implementation
    376     public int getIntExtra(String name, int defaultValue) {
    377         return extras.getInt(name, defaultValue);
    378     }
    379 
    380     @Implementation
    381     public long getLongExtra(String name, long defaultValue) {
    382         return extras.getLong(name, defaultValue);
    383     }
    384 
    385     @Implementation
    386     public double getDoubleExtra(String name, double defaultValue) {
    387         return extras.getDouble(name, defaultValue);
    388     }
    389 
    390     @Implementation
    391     public Bundle getBundleExtra(String name) {
    392         return extras.getBundle(name);
    393     }
    394 
    395     @Implementation
    396     public float getFloatExtra(String name, float defaultValue) {
    397         return extras.getFloat(name, defaultValue);
    398     }
    399 
    400     @Implementation
    401     public byte[] getByteArrayExtra(String name) {
    402         return extras.getByteArray(name);
    403     }
    404 
    405     @Implementation
    406     public Serializable getSerializableExtra(String name) {
    407         return extras.getSerializable(name);
    408     }
    409 
    410     @Implementation
    411     public void removeExtra(String name) {
    412         extras.remove(name);
    413     }
    414 
    415     @Implementation
    416     public Intent setComponent(ComponentName componentName) {
    417         this.componentName = componentName;
    418         return realIntent;
    419     }
    420 
    421     @Implementation
    422     public ComponentName getComponent() {
    423         return componentName;
    424     }
    425 
    426     @Implementation
    427     public int fillIn(Intent otherIntent, int flags) {
    428         int changes = 0;
    429         ShadowIntent other = shadowOf(otherIntent);
    430 
    431         if (other.action != null && (action == null || (flags & FILL_IN_ACTION) != 0)) {
    432             action = other.action;
    433             changes |= FILL_IN_ACTION;
    434         }
    435         if ((other.data != null || other.type != null)
    436                 && ((data == null && type == null) || (flags & FILL_IN_DATA) != 0)) {
    437             data = other.data;
    438             type = other.type;
    439             changes |= FILL_IN_DATA;
    440         }
    441         if (!other.categories.isEmpty()
    442                 && (categories.isEmpty() || (flags & FILL_IN_CATEGORIES) != 0)) {
    443             categories.addAll(other.categories);
    444             changes |= FILL_IN_CATEGORIES;
    445         }
    446         if (other.packageName != null
    447                 && (packageName == null || (flags & FILL_IN_PACKAGE) != 0)) {
    448             packageName = other.packageName;
    449             changes |= FILL_IN_PACKAGE;
    450         }
    451         if (other.componentName != null && (flags & FILL_IN_COMPONENT) != 0) {
    452             componentName = other.componentName;
    453             changes |= FILL_IN_COMPONENT;
    454         }
    455 
    456         extras.putAll(other.extras);
    457         return changes;
    458     }
    459 
    460     @Implementation
    461     // cribbed from Android source
    462     public boolean filterEquals(Intent other) {
    463         if (other == null) {
    464             return false;
    465         }
    466         if (getAction() != other.getAction()) {
    467             if (getAction() != null) {
    468                 if (!getAction().equals(other.getAction())) {
    469                     return false;
    470                 }
    471             } else {
    472                 if (!other.getAction().equals(getAction())) {
    473                     return false;
    474                 }
    475             }
    476         }
    477         if (getData() != other.getData()) {
    478             if (getData() != null) {
    479                 if (!getData().equals(other.getData())) {
    480                     return false;
    481                 }
    482             } else {
    483                 if (!other.getData().equals(getData())) {
    484                     return false;
    485                 }
    486             }
    487         }
    488         if (getType() != other.getType()) {
    489             if (getType() != null) {
    490                 if (!getType().equals(other.getType())) {
    491                     return false;
    492                 }
    493             } else {
    494                 if (!other.getType().equals(getType())) {
    495                     return false;
    496                 }
    497             }
    498         }
    499         if (getPackage() != other.getPackage()) {
    500             if (getPackage() != null) {
    501                 if (!getPackage().equals(other.getPackage())) {
    502                     return false;
    503                 }
    504             } else {
    505                 if (!other.getPackage().equals(getPackage())) {
    506                     return false;
    507                 }
    508             }
    509         }
    510         if (getComponent() != other.getComponent()) {
    511             if (getComponent() != null) {
    512                 if (!getComponent().equals(other.getComponent())) {
    513                     return false;
    514                 }
    515             } else {
    516                 if (!other.getComponent().equals(getComponent())) {
    517                     return false;
    518                 }
    519             }
    520         }
    521         if (getCategories() != other.getCategories()) {
    522             if (getCategories() != null) {
    523                 if (!getCategories().equals(other.getCategories())) {
    524                     return false;
    525                 }
    526             } else {
    527                 if (!other.getCategories().equals(getCategories())) {
    528                     return false;
    529                 }
    530             }
    531         }
    532 
    533         return true;
    534     }
    535 
    536     /**
    537      * Compares an {@code Intent} with a {@code ShadowIntent} (obtained via a call to
    538      * {@link Robolectric#shadowOf(android.content.Intent)})
    539      *
    540      * @param o a {@code ShadowIntent}
    541      * @return whether they are equivalent
    542      */
    543     @Deprecated
    544     public boolean realIntentEquals(ShadowIntent o) {
    545         if (this == o) return true;
    546         if (o == null || getClass() != o.getClass()) return false;
    547 
    548         if (action != null ? !action.equals(o.action) : o.action != null) return false;
    549         if (componentName != null ? !componentName.equals(o.componentName) : o.componentName != null)
    550             return false;
    551         if (data != null ? !data.equals(o.data) : o.data != null) return false;
    552         if (extras != null ? !extras.equals(o.extras) : o.extras != null) return false;
    553         if (type != null ? !type.equals(o.type) : o.type != null) return false;
    554         if (categories != null ? !categories.equals(o.categories) : o.categories != null) return false;
    555 
    556         return true;
    557     }
    558 
    559     @Override
    560     @Implementation
    561     public int hashCode() {
    562         int result = extras != null ? extras.hashCode() : 0;
    563         result = 31 * result + (action != null ? action.hashCode() : 0);
    564         result = 31 * result + (componentName != null ? componentName.hashCode() : 0);
    565         result = 31 * result + (data != null ? data.hashCode() : 0);
    566         result = 31 * result + (type != null ? type.hashCode() : 0);
    567         result = 31 * result + flags;
    568         return result;
    569     }
    570 
    571     @Override
    572     @Implementation
    573     public boolean equals(Object o) {
    574         if (!(o instanceof Intent)) return false;
    575         return realIntentEquals(shadowOf((Intent) o));
    576     }
    577 
    578     /**
    579      * Non-Android accessor that returns the {@code Class} object set by
    580      * {@link #setClass(android.content.Context, Class)}
    581      *
    582      * @return the {@code Class} object set by
    583      *         {@link #setClass(android.content.Context, Class)}
    584      */
    585     public Class<?> getIntentClass() {
    586         return intentClass;
    587     }
    588 
    589     @Override
    590     @Implementation
    591     public String toString() {
    592         return "Intent{" +
    593                 Join.join(
    594                         ", ",
    595                         ifWeHave(componentName, "componentName"),
    596                         ifWeHave(action, "action"),
    597                         ifWeHave(extras, "extras"),
    598                         ifWeHave(data, "data"),
    599                         ifWeHave(type, "type")
    600                 ) +
    601                 '}';
    602     }
    603 
    604     @Implementation
    605     public void writeToParcel(Parcel out, int flags) {
    606         out.writeString(action);
    607         if (data != null) {
    608             out.writeInt(1);
    609             Uri.writeToParcel(out, data);
    610         } else {
    611             out.writeInt(-1);
    612         }
    613         out.writeString(type);
    614         out.writeInt(flags);
    615         out.writeString(packageName);
    616         ComponentName.writeToParcel(componentName, out);
    617         out.writeInt(categories.size());
    618 
    619         for (String category : categories) {
    620             out.writeString(category);
    621         }
    622         out.writeBundle(extras);
    623     }
    624 
    625     @Implementation
    626     public void readFromParcel(Parcel in) {
    627         setAction(in.readString());
    628         if (in.readInt() == 1) {
    629             data = Uri.CREATOR.createFromParcel(in);
    630         }
    631         type = in.readString();
    632         flags = in.readInt();
    633         packageName = in.readString();
    634         componentName = ComponentName.readFromParcel(in);
    635         int N = in.readInt();
    636         for (int i = 0; i < N; i++) {
    637             categories.add(in.readString().intern());
    638         }
    639         extras.putAll(in.readBundle());
    640     }
    641 
    642     private Serializable serializeCycle(Serializable serializable) {
    643         try {
    644             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    645             ObjectOutputStream output = new ObjectOutputStream(byteArrayOutputStream);
    646             output.writeObject(serializable);
    647             output.close();
    648 
    649             byte[] bytes = byteArrayOutputStream.toByteArray();
    650             ObjectInputStream input = new ObjectInputStream(new ByteArrayInputStream(bytes));
    651             return (Serializable) input.readObject();
    652         } catch (IOException e) {
    653             throw new RuntimeException(e);
    654         } catch (ClassNotFoundException e) {
    655             throw new RuntimeException(e);
    656         }
    657     }
    658 
    659     private String ifWeHave(Object o, String name) {
    660         if (o == null) return null;
    661         if (o instanceof Map && ((Map) o).isEmpty()) return null;
    662         return name + "=" + o;
    663     }
    664 
    665     public static final Creator<Intent> CREATOR =
    666         new Creator<Intent>() {
    667             @Override
    668             public Intent createFromParcel(Parcel source) {
    669                 Intent intent = new Intent();
    670                 intent.readFromParcel(source);
    671                 return intent;
    672             }
    673 
    674             @Override
    675             public Intent[] newArray(int size) {
    676                 return new Intent[size];
    677             }
    678         };
    679 
    680     public static void reset() {
    681         Robolectric.Reflection.setFinalStaticField(Intent.class, "CREATOR", CREATOR);
    682     }
    683 }
    684