1package org.robolectric.android.controller;
2
3import android.content.ComponentName;
4import android.content.ContentProvider;
5import android.content.Context;
6import android.content.pm.PackageManager;
7import android.content.pm.ProviderInfo;
8import org.robolectric.RuntimeEnvironment;
9import org.robolectric.shadows.ShadowContentResolver;
10import org.robolectric.util.Logger;
11
12public class ContentProviderController<T extends ContentProvider>  {
13  private T contentProvider;
14
15  private ContentProviderController(T contentProvider) {
16    this.contentProvider = contentProvider;
17  }
18
19  public static <T extends ContentProvider> ContentProviderController<T> of(T contentProvider) {
20    return new ContentProviderController<>(contentProvider);
21  }
22
23  /**
24   * Create and register {@link ContentProvider} using {@link ProviderInfo} found from manifest.
25   */
26  public ContentProviderController<T> create() {
27    Context baseContext = RuntimeEnvironment.application.getBaseContext();
28
29    ComponentName componentName = createRelative(baseContext.getPackageName(), contentProvider.getClass().getName());
30
31    ProviderInfo providerInfo = null;
32    try {
33      providerInfo = baseContext.getPackageManager().getProviderInfo(componentName, 0);
34    } catch (PackageManager.NameNotFoundException e) {
35      Logger.strict("Unable to find provider info for " + componentName, e);
36    }
37
38    return create(providerInfo);
39  }
40
41  /**
42   * Create and register {@link ContentProvider} using {@link ProviderInfo} found from manifest.
43   *
44   * @param authority the authority to use
45   * @return this {@link ContentProviderController}
46   */
47  public ContentProviderController<T> create(String authority) {
48    ProviderInfo providerInfo = new ProviderInfo();
49    providerInfo.authority = authority;
50    return create(providerInfo);
51  }
52
53  /**
54   * Create and register {@link ContentProvider} using the given {@link ProviderInfo}.
55   *
56   * @param providerInfo the {@link ProviderInfo} to use
57   * @return this {@link ContentProviderController}
58   */
59  public ContentProviderController<T> create(ProviderInfo providerInfo) {
60    Context baseContext = RuntimeEnvironment.application.getBaseContext();
61    contentProvider.attachInfo(baseContext, providerInfo);
62
63    if (providerInfo != null) {
64      ShadowContentResolver.registerProviderInternal(providerInfo.authority, contentProvider);
65    }
66
67    return this;
68  }
69
70  public T get() {
71    return contentProvider;
72  }
73
74  public ContentProviderController<T> shutdown() {
75    contentProvider.shutdown();
76    return this;
77  }
78
79  private static ComponentName createRelative(String pkg, String cls) {
80    final String fullName;
81    if (cls.charAt(0) == '.') {
82      // Relative to the package. Prepend the package name.
83      fullName = pkg + cls;
84    } else {
85      // Fully qualified package name.
86      fullName = cls;
87    }
88    return new ComponentName(pkg, fullName);
89  }
90}
91