2020import com .android .internal .content .PackageMonitor ;
2121
2222import android .app .ActivityManager ;
23+ import android .app .ActivityManagerNative ;
2324import android .content .ComponentName ;
2425import android .content .Context ;
2526import android .content .Intent ;
3435import android .net .Uri ;
3536import android .os .Bundle ;
3637import android .os .PatternMatcher ;
38+ import android .os .Process ;
39+ import android .os .RemoteException ;
40+ import android .os .UserId ;
3741import android .util .Log ;
3842import android .view .LayoutInflater ;
3943import android .view .View ;
6165public class ResolverActivity extends AlertActivity implements AdapterView .OnItemClickListener {
6266 private static final String TAG = "ResolverActivity" ;
6367
68+ private int mLaunchedFromUid ;
6469 private ResolveListAdapter mAdapter ;
6570 private PackageManager mPm ;
6671 private boolean mAlwaysUseOption ;
@@ -102,6 +107,12 @@ protected void onCreate(Bundle savedInstanceState, Intent intent,
102107 boolean alwaysUseOption ) {
103108 setTheme (R .style .Theme_DeviceDefault_Light_Dialog_Alert );
104109 super .onCreate (savedInstanceState );
110+ try {
111+ mLaunchedFromUid = ActivityManagerNative .getDefault ().getLaunchedFromUid (
112+ getActivityToken ());
113+ } catch (RemoteException e ) {
114+ mLaunchedFromUid = -1 ;
115+ }
105116 mPm = getPackageManager ();
106117 mAlwaysUseOption = alwaysUseOption ;
107118 mMaxColumns = getResources ().getInteger (R .integer .config_maxResolverActivityColumns );
@@ -118,9 +129,14 @@ protected void onCreate(Bundle savedInstanceState, Intent intent,
118129 mIconDpi = am .getLauncherLargeIconDensity ();
119130 mIconSize = am .getLauncherLargeIconSize ();
120131
121- mAdapter = new ResolveListAdapter (this , intent , initialIntents , rList );
132+ mAdapter = new ResolveListAdapter (this , intent , initialIntents , rList ,
133+ mLaunchedFromUid );
122134 int count = mAdapter .getCount ();
123- if (count > 1 ) {
135+ if (mLaunchedFromUid < 0 || UserId .isIsolated (mLaunchedFromUid )) {
136+ // Gulp!
137+ finish ();
138+ return ;
139+ } else if (count > 1 ) {
124140 ap .mView = getLayoutInflater ().inflate (R .layout .resolver_grid , null );
125141 mGrid = (GridView ) ap .mView .findViewById (R .id .resolver_grid );
126142 mGrid .setAdapter (mAdapter );
@@ -146,9 +162,13 @@ protected void onCreate(Bundle savedInstanceState, Intent intent,
146162
147163 if (alwaysUseOption ) {
148164 final ViewGroup buttonLayout = (ViewGroup ) findViewById (R .id .button_bar );
149- buttonLayout .setVisibility (View .VISIBLE );
150- mAlwaysButton = (Button ) buttonLayout .findViewById (R .id .button_always );
151- mOnceButton = (Button ) buttonLayout .findViewById (R .id .button_once );
165+ if (buttonLayout != null ) {
166+ buttonLayout .setVisibility (View .VISIBLE );
167+ mAlwaysButton = (Button ) buttonLayout .findViewById (R .id .button_always );
168+ mOnceButton = (Button ) buttonLayout .findViewById (R .id .button_once );
169+ } else {
170+ mAlwaysUseOption = false ;
171+ }
152172 }
153173 }
154174
@@ -207,6 +227,18 @@ protected void onStop() {
207227 mPackageMonitor .unregister ();
208228 mRegistered = false ;
209229 }
230+ if ((getIntent ().getFlags ()&Intent .FLAG_ACTIVITY_NEW_TASK ) != 0 ) {
231+ // This resolver is in the unusual situation where it has been
232+ // launched at the top of a new task. We don't let it be added
233+ // to the recent tasks shown to the user, and we need to make sure
234+ // that each time we are launched we get the correct launching
235+ // uid (not re-using the same resolver from an old launching uid),
236+ // so we will now finish ourself since being no longer visible,
237+ // the user probably can't get back to us.
238+ if (!isChangingConfigurations ()) {
239+ finish ();
240+ }
241+ }
210242 }
211243
212244 @ Override
@@ -363,17 +395,19 @@ private final class ResolveListAdapter extends BaseAdapter {
363395 private final Intent [] mInitialIntents ;
364396 private final List <ResolveInfo > mBaseResolveList ;
365397 private final Intent mIntent ;
398+ private final int mLaunchedFromUid ;
366399 private final LayoutInflater mInflater ;
367400
368401 private List <ResolveInfo > mCurrentResolveList ;
369402 private List <DisplayResolveInfo > mList ;
370403
371404 public ResolveListAdapter (Context context , Intent intent ,
372- Intent [] initialIntents , List <ResolveInfo > rList ) {
405+ Intent [] initialIntents , List <ResolveInfo > rList , int launchedFromUid ) {
373406 mIntent = new Intent (intent );
374407 mIntent .setComponent (null );
375408 mInitialIntents = initialIntents ;
376409 mBaseResolveList = rList ;
410+ mLaunchedFromUid = launchedFromUid ;
377411 mInflater = (LayoutInflater )context .getSystemService (Context .LAYOUT_INFLATER_SERVICE );
378412 rebuildList ();
379413 }
@@ -400,6 +434,23 @@ private void rebuildList() {
400434 mCurrentResolveList = mPm .queryIntentActivities (
401435 mIntent , PackageManager .MATCH_DEFAULT_ONLY
402436 | (mAlwaysUseOption ? PackageManager .GET_RESOLVED_FILTER : 0 ));
437+ // Filter out any activities that the launched uid does not
438+ // have permission for. We don't do this when we have an explicit
439+ // list of resolved activities, because that only happens when
440+ // we are being subclassed, so we can safely launch whatever
441+ // they gave us.
442+ if (mCurrentResolveList != null ) {
443+ for (int i =mCurrentResolveList .size ()-1 ; i >= 0 ; i --) {
444+ ActivityInfo ai = mCurrentResolveList .get (i ).activityInfo ;
445+ int granted = ActivityManager .checkComponentPermission (
446+ ai .permission , mLaunchedFromUid ,
447+ ai .applicationInfo .uid , ai .exported );
448+ if (granted != PackageManager .PERMISSION_GRANTED ) {
449+ // Access not allowed!
450+ mCurrentResolveList .remove (i );
451+ }
452+ }
453+ }
403454 }
404455 int N ;
405456 if ((mCurrentResolveList != null ) && ((N = mCurrentResolveList .size ()) > 0 )) {
0 commit comments