diff options
author | Sam Blitzstein <sblitz@google.com> | 2014-12-12 20:20:58 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-12-12 20:20:58 +0000 |
commit | ee147a50c48a76c6a0d7deed4e6a5afadc96b5c5 (patch) | |
tree | a454c924b4797e9a060719eedc6387f89c48a336 | |
parent | 168e02aff896aecd689d44c3118186c11a0420a8 (diff) | |
parent | 109d19ccd3b6251e242c40cb560d3b2385472148 (diff) | |
download | android_packages_providers_CalendarProvider-ee147a50c48a76c6a0d7deed4e6a5afadc96b5c5.tar.gz android_packages_providers_CalendarProvider-ee147a50c48a76c6a0d7deed4e6a5afadc96b5c5.tar.bz2 android_packages_providers_CalendarProvider-ee147a50c48a76c6a0d7deed4e6a5afadc96b5c5.zip |
am 109d19cc: am 2dc73a40: am 96d67800: Before the first call to clearCallingIdentity, cache the calling package.
* commit '109d19ccd3b6251e242c40cb560d3b2385472148':
Before the first call to clearCallingIdentity, cache the calling package.
-rw-r--r-- | src/com/android/providers/calendar/CalendarProvider2.java | 9 | ||||
-rw-r--r-- | src/com/android/providers/calendar/SQLiteContentProvider.java | 75 |
2 files changed, 72 insertions, 12 deletions
diff --git a/src/com/android/providers/calendar/CalendarProvider2.java b/src/com/android/providers/calendar/CalendarProvider2.java index 9af4c77..5002177 100644 --- a/src/com/android/providers/calendar/CalendarProvider2.java +++ b/src/com/android/providers/calendar/CalendarProvider2.java @@ -834,11 +834,11 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - final long identity = Binder.clearCallingIdentity(); + final long identity = clearCallingIdentityInternal(); try { return queryInternal(uri, projection, selection, selectionArgs, sortOrder); } finally { - Binder.restoreCallingIdentity(identity); + restoreCallingIdentityInternal(identity); } } @@ -5074,6 +5074,11 @@ public class CalendarProvider2 extends SQLiteContentProvider implements OnAccoun } private String getCallingPackageName() { + if (getCachedCallingPackage() != null) { + // If the calling package is null, use the best available as a fallback. + return getCachedCallingPackage(); + } + final PackageManager pm = getContext().getPackageManager(); final int uid = Binder.getCallingUid(); final String[] packages = pm.getPackagesForUid(uid); diff --git a/src/com/android/providers/calendar/SQLiteContentProvider.java b/src/com/android/providers/calendar/SQLiteContentProvider.java index ad0e028..01afb23 100644 --- a/src/com/android/providers/calendar/SQLiteContentProvider.java +++ b/src/com/android/providers/calendar/SQLiteContentProvider.java @@ -27,6 +27,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteTransactionListener; import android.net.Uri; import android.os.Binder; +import android.os.Process; import android.provider.CalendarContract; import java.util.ArrayList; @@ -93,7 +94,7 @@ public abstract class SQLiteContentProvider extends ContentProvider if (!applyingBatch) { mDb = mOpenHelper.getWritableDatabase(); mDb.beginTransactionWithListener(this); - final long identity = Binder.clearCallingIdentity(); + final long identity = clearCallingIdentityInternal(); try { result = insertInTransaction(uri, values, isCallerSyncAdapter); if (result != null) { @@ -101,7 +102,7 @@ public abstract class SQLiteContentProvider extends ContentProvider } mDb.setTransactionSuccessful(); } finally { - Binder.restoreCallingIdentity(identity); + restoreCallingIdentityInternal(identity); mDb.endTransaction(); } @@ -121,7 +122,7 @@ public abstract class SQLiteContentProvider extends ContentProvider boolean isCallerSyncAdapter = getIsCallerSyncAdapter(uri); mDb = mOpenHelper.getWritableDatabase(); mDb.beginTransactionWithListener(this); - final long identity = Binder.clearCallingIdentity(); + final long identity = clearCallingIdentityInternal(); try { for (int i = 0; i < numValues; i++) { Uri result = insertInTransaction(uri, values[i], isCallerSyncAdapter); @@ -132,7 +133,7 @@ public abstract class SQLiteContentProvider extends ContentProvider } mDb.setTransactionSuccessful(); } finally { - Binder.restoreCallingIdentity(identity); + restoreCallingIdentityInternal(identity); mDb.endTransaction(); } @@ -148,7 +149,7 @@ public abstract class SQLiteContentProvider extends ContentProvider if (!applyingBatch) { mDb = mOpenHelper.getWritableDatabase(); mDb.beginTransactionWithListener(this); - final long identity = Binder.clearCallingIdentity(); + final long identity = clearCallingIdentityInternal(); try { count = updateInTransaction(uri, values, selection, selectionArgs, isCallerSyncAdapter); @@ -157,7 +158,7 @@ public abstract class SQLiteContentProvider extends ContentProvider } mDb.setTransactionSuccessful(); } finally { - Binder.restoreCallingIdentity(identity); + restoreCallingIdentityInternal(identity); mDb.endTransaction(); } @@ -181,7 +182,7 @@ public abstract class SQLiteContentProvider extends ContentProvider if (!applyingBatch) { mDb = mOpenHelper.getWritableDatabase(); mDb.beginTransactionWithListener(this); - final long identity = Binder.clearCallingIdentity(); + final long identity = clearCallingIdentityInternal(); try { count = deleteInTransaction(uri, selection, selectionArgs, isCallerSyncAdapter); if (count > 0) { @@ -189,7 +190,7 @@ public abstract class SQLiteContentProvider extends ContentProvider } mDb.setTransactionSuccessful(); } finally { - Binder.restoreCallingIdentity(identity); + restoreCallingIdentityInternal(identity); mDb.endTransaction(); } @@ -222,7 +223,7 @@ public abstract class SQLiteContentProvider extends ContentProvider mDb = mOpenHelper.getWritableDatabase(); mDb.beginTransactionWithListener(this); final boolean isCallerSyncAdapter = getIsCallerSyncAdapter(operations.get(0).getUri()); - final long identity = Binder.clearCallingIdentity(); + final long identity = clearCallingIdentityInternal(); try { mApplyingBatch.set(true); final ContentProviderResult[] results = new ContentProviderResult[numOperations]; @@ -239,7 +240,7 @@ public abstract class SQLiteContentProvider extends ContentProvider mApplyingBatch.set(false); mDb.endTransaction(); onEndTransaction(!isCallerSyncAdapter); - Binder.restoreCallingIdentity(identity); + restoreCallingIdentityInternal(identity); } } @@ -274,4 +275,58 @@ public abstract class SQLiteContentProvider extends ContentProvider * Some URI's are maintained locally so we should not request a sync for them */ protected abstract boolean shouldSyncFor(Uri uri); + + /** The package to most recently query(), not including further internally recursive calls. */ + private final ThreadLocal<String> mCallingPackage = new ThreadLocal<String>(); + + /** + * The calling Uid when a calling package is cached, so we know when the stack of any + * recursive calls to clearCallingIdentity and restoreCallingIdentity is complete. + */ + private final ThreadLocal<Integer> mOriginalCallingUid = new ThreadLocal<Integer>(); + + + protected String getCachedCallingPackage() { + return mCallingPackage.get(); + } + + /** + * Call {@link android.os.Binder#clearCallingIdentity()}, while caching the calling package + * name, so that it can be saved if this is part of an event mutation. + */ + protected long clearCallingIdentityInternal() { + // Only set the calling package if the calling UID is not our own. + int uid = Process.myUid(); + int callingUid = Binder.getCallingUid(); + if (uid != callingUid) { + try { + mOriginalCallingUid.set(callingUid); + String callingPackage = getCallingPackage(); + mCallingPackage.set(callingPackage); + } catch (SecurityException e) { + // If this exception is thrown, clearCallingIdentity has already been called, and + // calling package is already available. + } + } + + return Binder.clearCallingIdentity(); + } + + /** + * Call {@link Binder#restoreCallingIdentity(long)}. + * </p> + * If this is the last restore on the stack of calls to + * {@link android.os.Binder#clearCallingIdentity()}, then the cached calling package will also + * be cleared. + * @param identity + */ + protected void restoreCallingIdentityInternal(long identity) { + Binder.restoreCallingIdentity(identity); + + int callingUid = Binder.getCallingUid(); + if (mOriginalCallingUid.get() != null && mOriginalCallingUid.get() == callingUid) { + mCallingPackage.set(null); + mOriginalCallingUid.set(null); + } + } } |