diff options
Diffstat (limited to 'core/java/android/app')
-rw-r--r-- | core/java/android/app/Activity.java | 37 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 25 | ||||
-rw-r--r-- | core/java/android/app/ApplicationThreadNative.java | 22 | ||||
-rw-r--r-- | core/java/android/app/IApplicationThread.java | 9 | ||||
-rw-r--r-- | core/java/android/app/Instrumentation.java | 15 | ||||
-rw-r--r-- | core/java/android/app/LocalActivityManager.java | 5 |
6 files changed, 83 insertions, 30 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 4b705dd..148527f 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -693,6 +693,7 @@ public class Activity extends ContextThemeWrapper /*package*/ String mEmbeddedID; private Application mApplication; /*package*/ Intent mIntent; + /*package*/ String mReferrer; private ComponentName mComponent; /*package*/ ActivityInfo mActivityInfo; /*package*/ ActivityThread mMainThread; @@ -4448,6 +4449,39 @@ public class Activity extends ContextThemeWrapper } /** + * Return information about who launched this activity. If the launching Intent + * contains an {@link android.content.Intent#EXTRA_REFERRER Intent.EXTRA_REFERRER}, + * that will be returned as-is; otherwise, if known, an + * {@link Intent#URI_ANDROID_APP_SCHEME android-app:} referrer URI containing the + * package name that started the Intent will be returned. This may return null if no + * referrer can be identified -- it is neither explicitly specified, nor is it known which + * application package was involved. + * + * <p>If called while inside the handling of {@link #onNewIntent}, this function will + * return the referrer that submitted that new intent to the activity. Otherwise, it + * always returns the referrer of the original Intent.</p> + * + * <p>Note that this is <em>not</em> a security feature -- you can not trust the + * referrer information, applications can spoof it.</p> + */ + @Nullable + public Uri getReferrer() { + Intent intent = getIntent(); + Uri referrer = intent.getParcelableExtra(Intent.EXTRA_REFERRER); + if (referrer != null) { + return referrer; + } + String referrerName = intent.getStringExtra(Intent.EXTRA_REFERRER_NAME); + if (referrerName != null) { + return Uri.parse(referrerName); + } + if (mReferrer != null) { + return new Uri.Builder().scheme("android-app").authority(mReferrer).build(); + } + return null; + } + + /** * Return the name of the package that invoked this activity. This is who * the data in {@link #setResult setResult()} will be sent to. You can * use this information to validate that the recipient is allowed to @@ -5868,7 +5902,7 @@ public class Activity extends ContextThemeWrapper Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, - Configuration config, IVoiceInteractor voiceInteractor) { + Configuration config, String referrer, IVoiceInteractor voiceInteractor) { attachBaseContext(context); mFragments.attachActivity(this, mContainer, null); @@ -5891,6 +5925,7 @@ public class Activity extends ContextThemeWrapper mIdent = ident; mApplication = application; mIntent = intent; + mReferrer = referrer; mComponent = intent.getComponent(); mActivityInfo = info; mTitle = title; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index cf6c049..5f21d75 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -94,6 +94,7 @@ import android.renderscript.RenderScript; import android.security.AndroidKeyStoreProvider; import com.android.internal.app.IVoiceInteractor; +import com.android.internal.content.ReferrerIntent; import com.android.internal.os.BinderInternal; import com.android.internal.os.RuntimeInit; import com.android.internal.os.SamplingProfilerIntegration; @@ -268,6 +269,7 @@ public final class ActivityThread { IBinder token; int ident; Intent intent; + String referrer; IVoiceInteractor voiceInteractor; Bundle state; PersistableBundle persistentState; @@ -290,7 +292,7 @@ public final class ActivityThread { LoadedApk packageInfo; List<ResultInfo> pendingResults; - List<Intent> pendingIntents; + List<ReferrerIntent> pendingIntents; boolean startsNotResumed; boolean isForward; @@ -348,7 +350,7 @@ public final class ActivityThread { } static final class NewIntentData { - List<Intent> intents; + List<ReferrerIntent> intents; IBinder token; public String toString() { return "NewIntentData{intents=" + intents + " token=" + token + "}"; @@ -605,9 +607,9 @@ public final class ActivityThread { // activity itself back to the activity manager. (matters more with ipc) public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, - IVoiceInteractor voiceInteractor, int procState, Bundle state, + String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, + List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); @@ -617,6 +619,7 @@ public final class ActivityThread { r.token = token; r.ident = ident; r.intent = intent; + r.referrer = referrer; r.voiceInteractor = voiceInteractor; r.activityInfo = info; r.compatInfo = compatInfo; @@ -637,13 +640,13 @@ public final class ActivityThread { } public final void scheduleRelaunchActivity(IBinder token, - List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, + List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config) { requestRelaunchActivity(token, pendingResults, pendingNewIntents, configChanges, notResumed, config, true); } - public final void scheduleNewIntent(List<Intent> intents, IBinder token) { + public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) { NewIntentData data = new NewIntentData(); data.intents = intents; data.token = token; @@ -2234,7 +2237,7 @@ public final class ActivityThread { activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, - r.voiceInteractor); + r.referrer, r.voiceInteractor); if (customIntent != null) { activity.mIntent = customIntent; @@ -2421,8 +2424,7 @@ public final class ActivityThread { } } - private void deliverNewIntents(ActivityClientRecord r, - List<Intent> intents) { + private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) { final int N = intents.size(); for (int i=0; i<N; i++) { Intent intent = intents.get(i); @@ -2433,8 +2435,7 @@ public final class ActivityThread { } } - public final void performNewIntents(IBinder token, - List<Intent> intents) { + public final void performNewIntents(IBinder token, List<ReferrerIntent> intents) { ActivityClientRecord r = mActivities.get(token); if (r != null) { final boolean resumed = !r.paused; @@ -3752,7 +3753,7 @@ public final class ActivityThread { } public final void requestRelaunchActivity(IBinder token, - List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, + List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config, boolean fromServer) { ActivityClientRecord target = null; diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index 0123e16..d1b77b9 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -36,6 +36,7 @@ import android.os.IBinder; import android.os.Parcel; import android.os.ParcelFileDescriptor; import com.android.internal.app.IVoiceInteractor; +import com.android.internal.content.ReferrerIntent; import java.io.FileDescriptor; import java.io.IOException; @@ -140,19 +141,21 @@ public abstract class ApplicationThreadNative extends Binder ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data); Configuration curConfig = Configuration.CREATOR.createFromParcel(data); CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); + String referrer = data.readString(); IVoiceInteractor voiceInteractor = IVoiceInteractor.Stub.asInterface( data.readStrongBinder()); int procState = data.readInt(); Bundle state = data.readBundle(); PersistableBundle persistentState = data.readPersistableBundle(); List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR); - List<Intent> pi = data.createTypedArrayList(Intent.CREATOR); + List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR); boolean notResumed = data.readInt() != 0; boolean isForward = data.readInt() != 0; ProfilerInfo profilerInfo = data.readInt() != 0 ? ProfilerInfo.CREATOR.createFromParcel(data) : null; - scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, voiceInteractor, - procState, state, persistentState, ri, pi, notResumed, isForward, profilerInfo); + scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, referrer, + voiceInteractor, procState, state, persistentState, ri, pi, + notResumed, isForward, profilerInfo); return true; } @@ -161,7 +164,7 @@ public abstract class ApplicationThreadNative extends Binder data.enforceInterface(IApplicationThread.descriptor); IBinder b = data.readStrongBinder(); List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR); - List<Intent> pi = data.createTypedArrayList(Intent.CREATOR); + List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR); int configChanges = data.readInt(); boolean notResumed = data.readInt() != 0; Configuration config = null; @@ -175,7 +178,7 @@ public abstract class ApplicationThreadNative extends Binder case SCHEDULE_NEW_INTENT_TRANSACTION: { data.enforceInterface(IApplicationThread.descriptor); - List<Intent> pi = data.createTypedArrayList(Intent.CREATOR); + List<ReferrerIntent> pi = data.createTypedArrayList(ReferrerIntent.CREATOR); IBinder b = data.readStrongBinder(); scheduleNewIntent(pi, b); return true; @@ -764,9 +767,9 @@ class ApplicationThreadProxy implements IApplicationThread { public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, - IVoiceInteractor voiceInteractor, int procState, Bundle state, + String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, + List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); @@ -776,6 +779,7 @@ class ApplicationThreadProxy implements IApplicationThread { info.writeToParcel(data, 0); curConfig.writeToParcel(data, 0); compatInfo.writeToParcel(data, 0); + data.writeString(referrer); data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null); data.writeInt(procState); data.writeBundle(state); @@ -796,7 +800,7 @@ class ApplicationThreadProxy implements IApplicationThread { } public final void scheduleRelaunchActivity(IBinder token, - List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, + List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config) throws RemoteException { Parcel data = Parcel.obtain(); @@ -817,7 +821,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.recycle(); } - public void scheduleNewIntent(List<Intent> intents, IBinder token) + public void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index f53075c..42acbc6 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -35,6 +35,7 @@ import android.os.IBinder; import android.os.IInterface; import android.service.voice.IVoiceInteractionSession; import com.android.internal.app.IVoiceInteractor; +import com.android.internal.content.ReferrerIntent; import java.io.FileDescriptor; import java.util.List; @@ -59,14 +60,14 @@ public interface IApplicationThread extends IInterface { void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException; void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, - IVoiceInteractor voiceInteractor, int procState, Bundle state, + String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, + List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException; void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, int configChanges, + List<ReferrerIntent> pendingNewIntents, int configChanges, boolean notResumed, Configuration config) throws RemoteException; - void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException; + void scheduleNewIntent(List<ReferrerIntent> intent, IBinder token) throws RemoteException; void scheduleDestroyActivity(IBinder token, boolean finished, int configChanges) throws RemoteException; void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index 60a013e..d96153a 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -45,6 +45,7 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.ViewConfiguration; import android.view.Window; +import com.android.internal.content.ReferrerIntent; import java.io.File; import java.util.ArrayList; @@ -1042,7 +1043,7 @@ public class Instrumentation { activity.attach(context, aThread, this, token, 0, application, intent, info, title, parent, id, (Activity.NonConfigurationInstances)lastNonConfigurationInstance, - new Configuration(), null); + new Configuration(), null, null); return activity; } @@ -1207,7 +1208,17 @@ public class Instrumentation { * @param intent The new intent being received. */ public void callActivityOnNewIntent(Activity activity, Intent intent) { - activity.onNewIntent(intent); + final String oldReferrer = activity.mReferrer; + try { + try { + activity.mReferrer = ((ReferrerIntent)intent).mReferrer; + } catch (ClassCastException e) { + activity.mReferrer = null; + } + activity.onNewIntent(intent); + } finally { + activity.mReferrer = oldReferrer; + } } /** diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java index b654a6a..873e337 100644 --- a/core/java/android/app/LocalActivityManager.java +++ b/core/java/android/app/LocalActivityManager.java @@ -22,6 +22,7 @@ import android.os.Binder; import android.os.Bundle; import android.util.Log; import android.view.Window; +import com.android.internal.content.ReferrerIntent; import java.util.ArrayList; import java.util.HashMap; @@ -310,8 +311,8 @@ public class LocalActivityManager { if (aInfo.launchMode != ActivityInfo.LAUNCH_MULTIPLE || (intent.getFlags()&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0) { // The activity wants onNewIntent() called. - ArrayList<Intent> intents = new ArrayList<Intent>(1); - intents.add(intent); + ArrayList<ReferrerIntent> intents = new ArrayList<>(1); + intents.add(new ReferrerIntent(intent, mParent.getPackageName())); if (localLOGV) Log.v(TAG, r.id + ": new intent"); mActivityThread.performNewIntents(r, intents); r.intent = intent; |