diff --git a/README.md b/README.md
index 33f50de..36dca73 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,17 @@
[](https://travis-ci.org/grandcentrix/tray) [](https://github.com/grandcentrix/tray/blob/master/LICENSE.txt)
+## Why I fork this?
+[grandcentrix/tray](https://github.com/grandcentrix/tray)'s ContentProvider is running in the app main process. But sometimes we (as app developers) may want to have it running in another process (say, ":service" process). So this fork allows you to achieve it, by add below into app manifest:
+```
+
+
+```
+
+---
If you have read the documentation of the [`SharedPreferences`](http://developer.android.com/reference/android/content/SharedPreferences.html) you might have seen one of these warnings:
>Note: currently this class does not support use across multiple processes. This will be added later.
diff --git a/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayContractTest.java b/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayContractTest.java
index 0dd0229..cb5a8df 100644
--- a/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayContractTest.java
+++ b/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayContractTest.java
@@ -65,6 +65,30 @@ public void testGenerateInternalContentUri_WithCorrectProvider_ShouldWork()
assertEquals("my.custom.authority", TrayContract.sAuthority);
}
+
+ public void testGenerateInternalContentUri_WithNameNotFoundExp_AppShouldCrash(){
+ final List mockProviders = new ArrayList<>();
+
+ ProviderInfo wrongInfo = new ProviderInfo();
+ wrongInfo.authority = "wrong";
+ wrongInfo.name = "wrong";
+ mockProviders.add(wrongInfo);
+
+ ProviderInfo info = new ProviderInfo();
+ info.authority = "my.custom.authority";
+ info.name = TrayContentProvider.class.getName();
+ mockProviders.add(info);
+
+ getProviderMockContext().setProviderInfos(mockProviders);
+ getProviderMockContext().setThrowNameNotFoundFromPackageManager(true);
+
+ try {
+ TrayContract.generateInternalContentUri(getProviderMockContext());
+ fail("did not throw");
+ } catch (TrayRuntimeException e) {
+ assertTrue(e.getMessage().contains("Internal tray error"));
+ }
+ }
public void testGenerateInternalContentUri_WithWrongProviders_AppShouldCrash()
throws Exception {
diff --git a/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayProviderTestCase.java b/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayProviderTestCase.java
index 7eb416c..1ce2cf0 100644
--- a/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayProviderTestCase.java
+++ b/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayProviderTestCase.java
@@ -24,6 +24,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
@@ -47,6 +48,8 @@ public abstract class TrayProviderTestCase extends ProviderTestCase2 mProviderInfos;
@@ -73,6 +76,10 @@ public void enableMockResolver(final boolean enabled) {
mHasMockResolver = enabled;
}
+ public void setThrowNameNotFoundFromPackageManager(final boolean shouldThrow){
+ mThrowNameNotFoundFromPm = shouldThrow;
+ }
+
@Override
public Context getApplicationContext() {
return innerContext;
@@ -121,6 +128,18 @@ public List queryContentProviders(final String processName,
final int uid, final int flags) {
return mProviderInfos;
}
+
+ @Override
+ public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
+ if(mThrowNameNotFoundFromPm) throw new NameNotFoundException();
+ else {
+ final PackageInfo pkgInfo = new PackageInfo();
+ if (null != mProviderInfos) {
+ pkgInfo.providers = mProviderInfos.toArray(new ProviderInfo[mProviderInfos.size()]);
+ }
+ return pkgInfo;
+ }
+ }
};
}
diff --git a/library/src/main/java/net/grandcentrix/tray/provider/TrayContract.java b/library/src/main/java/net/grandcentrix/tray/provider/TrayContract.java
index eb33c4b..2e64cf4 100644
--- a/library/src/main/java/net/grandcentrix/tray/provider/TrayContract.java
+++ b/library/src/main/java/net/grandcentrix/tray/provider/TrayContract.java
@@ -21,16 +21,15 @@
import net.grandcentrix.tray.core.TrayRuntimeException;
import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.net.Uri;
-import android.os.Process;
import android.provider.BaseColumns;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
-import java.util.List;
-
/**
* Contract defining the data in the {@link TrayContentProvider}. Use {@link TrayProviderHelper} to
* access them.
@@ -120,20 +119,23 @@ private static synchronized String getAuthority(@NonNull final Context context)
}
checkOldWayToSetAuthority(context);
-
- // read all providers of the app and find the TrayContentProvider to read the authority
- final List providers = context.getPackageManager()
- .queryContentProviders(context.getPackageName(), Process.myUid(), 0);
- if (providers != null) {
- for (ProviderInfo provider : providers) {
- if (provider.name.equals(TrayContentProvider.class.getName())) {
- sAuthority = provider.authority;
- TrayLog.v("found authority: " + sAuthority);
- return sAuthority;
+
+ try {
+ final PackageInfo pkgInfo = context.getPackageManager()
+ .getPackageInfo(context.getPackageName(), PackageManager.GET_PROVIDERS);
+ if(null != pkgInfo.providers){
+ for (ProviderInfo provider : pkgInfo.providers) {
+ if (provider.name.equals(TrayContentProvider.class.getName())) {
+ sAuthority = provider.authority;
+ TrayLog.v("found authority: " + sAuthority);
+ return sAuthority;
+ }
}
}
+ } catch (final PackageManager.NameNotFoundException e) {
+ Log.e("Tray", "Unable to get PackageInfo of current package " + context.getPackageName(), e);
}
-
+
// Should never happen. Otherwise we implemented tray in a wrong way!
throw new TrayRuntimeException("Internal tray error. "
+ "Could not find the provider authority. "