From 85a2efd1c7b7be18157453d88fae6540bac225ec Mon Sep 17 00:00:00 2001 From: vliux_shuwen Date: Wed, 26 Jul 2017 14:19:58 +0800 Subject: [PATCH 1/4] Fix: support querying provider authority regardless of the hosting app process. --- .../tray/provider/TrayProviderTestCase.java | 10 +++++++ .../tray/publicapi/ReadDifferentFormat.java | 2 +- .../tray/provider/TrayContract.java | 30 ++++++++++--------- 3 files changed, 27 insertions(+), 15 deletions(-) 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..cea827d 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; @@ -121,6 +122,15 @@ public List queryContentProviders(final String processName, final int uid, final int flags) { return mProviderInfos; } + + @Override + public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException { + final PackageInfo pkgInfo = new PackageInfo(); + if(null != mProviderInfos) { + pkgInfo.providers = mProviderInfos.toArray(new ProviderInfo[mProviderInfos.size()]); + } + return pkgInfo; + } }; } diff --git a/library/src/androidTest/java/net/grandcentrix/tray/publicapi/ReadDifferentFormat.java b/library/src/androidTest/java/net/grandcentrix/tray/publicapi/ReadDifferentFormat.java index 4dafc83..85a3d46 100644 --- a/library/src/androidTest/java/net/grandcentrix/tray/publicapi/ReadDifferentFormat.java +++ b/library/src/androidTest/java/net/grandcentrix/tray/publicapi/ReadDifferentFormat.java @@ -78,7 +78,7 @@ public void testReadLongAsWrongType() throws Exception { assertEquals(Long.MAX_VALUE, mPref.getInt(KEY)); fail(); } catch (WrongTypeException e) { - assertTrue(e.getMessage().contains("int")); + assertTrue(e.getMessage().contains("string")); } } 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. " From cde680b49faebb93f8a57bccf35c17d19e778a87 Mon Sep 17 00:00:00 2001 From: vliux_shuwen Date: Wed, 26 Jul 2017 15:27:43 +0800 Subject: [PATCH 2/4] Revery un-neccessary fix on testReadLongAsWrongType: exception msg on AVD contains 'int'. --- .../net/grandcentrix/tray/publicapi/ReadDifferentFormat.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/androidTest/java/net/grandcentrix/tray/publicapi/ReadDifferentFormat.java b/library/src/androidTest/java/net/grandcentrix/tray/publicapi/ReadDifferentFormat.java index 85a3d46..4dafc83 100644 --- a/library/src/androidTest/java/net/grandcentrix/tray/publicapi/ReadDifferentFormat.java +++ b/library/src/androidTest/java/net/grandcentrix/tray/publicapi/ReadDifferentFormat.java @@ -78,7 +78,7 @@ public void testReadLongAsWrongType() throws Exception { assertEquals(Long.MAX_VALUE, mPref.getInt(KEY)); fail(); } catch (WrongTypeException e) { - assertTrue(e.getMessage().contains("string")); + assertTrue(e.getMessage().contains("int")); } } From 2c977606616c51a588434a9c28104cf5c0795fc3 Mon Sep 17 00:00:00 2001 From: LiuXin Date: Wed, 26 Jul 2017 16:44:47 +0800 Subject: [PATCH 3/4] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 33f50de..36dca73 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,17 @@ [![Build Status](https://travis-ci.org/grandcentrix/tray.svg?branch=master)](https://travis-ci.org/grandcentrix/tray) [![License](https://img.shields.io/badge/license-Apache%202-green.svg?style=flat)](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. From dccb1c254bbccf5ed4ec5de897f56369f136036a Mon Sep 17 00:00:00 2001 From: vliux_shuwen Date: Fri, 28 Jul 2017 14:20:20 +0800 Subject: [PATCH 4/4] Add one more test case for NameNotFoundException code branch in TrayContract.getAuthority(). --- .../tray/provider/TrayContractTest.java | 24 +++++++++++++++++++ .../tray/provider/TrayProviderTestCase.java | 17 +++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) 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 cea827d..1ce2cf0 100644 --- a/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayProviderTestCase.java +++ b/library/src/androidTest/java/net/grandcentrix/tray/provider/TrayProviderTestCase.java @@ -48,6 +48,8 @@ public abstract class TrayProviderTestCase extends ProviderTestCase2 mProviderInfos; @@ -74,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; @@ -125,11 +131,14 @@ public List queryContentProviders(final String processName, @Override public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException { - final PackageInfo pkgInfo = new PackageInfo(); - if(null != mProviderInfos) { - pkgInfo.providers = mProviderInfos.toArray(new ProviderInfo[mProviderInfos.size()]); + if(mThrowNameNotFoundFromPm) throw new NameNotFoundException(); + else { + final PackageInfo pkgInfo = new PackageInfo(); + if (null != mProviderInfos) { + pkgInfo.providers = mProviderInfos.toArray(new ProviderInfo[mProviderInfos.size()]); + } + return pkgInfo; } - return pkgInfo; } }; }