Loading core/java/android/app/Activity.java +2 −1 Original line number Diff line number Diff line Loading @@ -4999,7 +4999,8 @@ public class Activity extends ContextThemeWrapper mCurrentConfig = config; } final IBinder getActivityToken() { /** @hide */ public final IBinder getActivityToken() { return mParent != null ? mParent.getActivityToken() : mToken; } Loading core/java/android/app/ActivityManager.java +37 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.ConfigurationInfo; import android.content.pm.IPackageDataObserver; import android.content.res.Configuration; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; Loading @@ -36,16 +36,17 @@ import android.os.Debug; import android.os.Handler; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserId; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; import android.view.Display; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; Loading Loading @@ -1798,6 +1799,40 @@ public class ActivityManager { } } /** @hide */ public static int checkComponentPermission(String permission, int uid, int owningUid, boolean exported) { // Root, system server get to do everything. if (uid == 0 || uid == Process.SYSTEM_UID) { return PackageManager.PERMISSION_GRANTED; } // Isolated processes don't get any permissions. if (UserId.isIsolated(uid)) { return PackageManager.PERMISSION_DENIED; } // If there is a uid that owns whatever is being accessed, it has // blanket access to it regardless of the permissions it requires. if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) { return PackageManager.PERMISSION_GRANTED; } // If the target is not exported, then nobody else can get to it. if (!exported) { Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid); return PackageManager.PERMISSION_DENIED; } if (permission == null) { return PackageManager.PERMISSION_GRANTED; } try { return AppGlobals.getPackageManager() .checkUidPermission(permission, uid); } catch (RemoteException e) { // Should never happen, but if it does... deny! Slog.e(TAG, "PackageManager is dead?!?", e); } return PackageManager.PERMISSION_DENIED; } /** * Returns the usage statistics of each installed package. * Loading core/java/android/app/ActivityManagerNative.java +22 −0 Original line number Diff line number Diff line Loading @@ -1656,6 +1656,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case GET_LAUNCHED_FROM_UID_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); int res = getLaunchedFromUid(token); reply.writeNoException(); reply.writeInt(res); return true; } } return super.onTransact(code, data, reply, flags); Loading Loading @@ -3785,5 +3794,18 @@ class ActivityManagerProxy implements IActivityManager return result; } public int getLaunchedFromUid(IBinder activityToken) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(activityToken); mRemote.transact(GET_LAUNCHED_FROM_UID_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); data.recycle(); reply.recycle(); return result; } private IBinder mRemote; } core/java/android/app/IActivityManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -350,6 +350,10 @@ public interface IActivityManager extends IInterface { public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData) throws RemoteException; // This is not public because you need to be very careful in how you // manage your activity to make sure it is always the uid you expect. public int getLaunchedFromUid(IBinder activityToken) throws RemoteException; /* * Private non-Binder interfaces */ Loading Loading @@ -592,4 +596,5 @@ public interface IActivityManager extends IInterface { int NAVIGATE_UP_TO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+146; int SET_LOCK_SCREEN_SHOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+147; int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148; int GET_LAUNCHED_FROM_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+149; } core/java/com/android/internal/app/ResolverActivity.java +57 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import com.android.internal.R; import com.android.internal.content.PackageMonitor; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -34,6 +35,9 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.PatternMatcher; import android.os.Process; import android.os.RemoteException; import android.os.UserId; import android.util.Log; import android.view.LayoutInflater; import android.view.View; Loading Loading @@ -61,6 +65,7 @@ import java.util.Set; public class ResolverActivity extends AlertActivity implements AdapterView.OnItemClickListener { private static final String TAG = "ResolverActivity"; private int mLaunchedFromUid; private ResolveListAdapter mAdapter; private PackageManager mPm; private boolean mAlwaysUseOption; Loading Loading @@ -102,6 +107,12 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte boolean alwaysUseOption) { setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert); super.onCreate(savedInstanceState); try { mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid( getActivityToken()); } catch (RemoteException e) { mLaunchedFromUid = -1; } mPm = getPackageManager(); mAlwaysUseOption = alwaysUseOption; mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns); Loading @@ -118,9 +129,14 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte mIconDpi = am.getLauncherLargeIconDensity(); mIconSize = am.getLauncherLargeIconSize(); mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList); mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList, mLaunchedFromUid); int count = mAdapter.getCount(); if (count > 1) { if (mLaunchedFromUid < 0 || UserId.isIsolated(mLaunchedFromUid)) { // Gulp! finish(); return; } else if (count > 1) { ap.mView = getLayoutInflater().inflate(R.layout.resolver_grid, null); mGrid = (GridView) ap.mView.findViewById(R.id.resolver_grid); mGrid.setAdapter(mAdapter); Loading @@ -146,9 +162,13 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte if (alwaysUseOption) { final ViewGroup buttonLayout = (ViewGroup) findViewById(R.id.button_bar); if (buttonLayout != null) { buttonLayout.setVisibility(View.VISIBLE); mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always); mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once); } else { mAlwaysUseOption = false; } } } Loading Loading @@ -207,6 +227,18 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte mPackageMonitor.unregister(); mRegistered = false; } if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { // This resolver is in the unusual situation where it has been // launched at the top of a new task. We don't let it be added // to the recent tasks shown to the user, and we need to make sure // that each time we are launched we get the correct launching // uid (not re-using the same resolver from an old launching uid), // so we will now finish ourself since being no longer visible, // the user probably can't get back to us. if (!isChangingConfigurations()) { finish(); } } } @Override Loading Loading @@ -363,17 +395,19 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte private final Intent[] mInitialIntents; private final List<ResolveInfo> mBaseResolveList; private final Intent mIntent; private final int mLaunchedFromUid; private final LayoutInflater mInflater; private List<ResolveInfo> mCurrentResolveList; private List<DisplayResolveInfo> mList; public ResolveListAdapter(Context context, Intent intent, Intent[] initialIntents, List<ResolveInfo> rList) { Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid) { mIntent = new Intent(intent); mIntent.setComponent(null); mInitialIntents = initialIntents; mBaseResolveList = rList; mLaunchedFromUid = launchedFromUid; mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); rebuildList(); } Loading @@ -400,6 +434,23 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte mCurrentResolveList = mPm.queryIntentActivities( mIntent, PackageManager.MATCH_DEFAULT_ONLY | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0)); // Filter out any activities that the launched uid does not // have permission for. We don't do this when we have an explicit // list of resolved activities, because that only happens when // we are being subclassed, so we can safely launch whatever // they gave us. if (mCurrentResolveList != null) { for (int i=mCurrentResolveList.size()-1; i >= 0; i--) { ActivityInfo ai = mCurrentResolveList.get(i).activityInfo; int granted = ActivityManager.checkComponentPermission( ai.permission, mLaunchedFromUid, ai.applicationInfo.uid, ai.exported); if (granted != PackageManager.PERMISSION_GRANTED) { // Access not allowed! mCurrentResolveList.remove(i); } } } } int N; if ((mCurrentResolveList != null) && ((N = mCurrentResolveList.size()) > 0)) { Loading Loading
core/java/android/app/Activity.java +2 −1 Original line number Diff line number Diff line Loading @@ -4999,7 +4999,8 @@ public class Activity extends ContextThemeWrapper mCurrentConfig = config; } final IBinder getActivityToken() { /** @hide */ public final IBinder getActivityToken() { return mParent != null ? mParent.getActivityToken() : mToken; } Loading
core/java/android/app/ActivityManager.java +37 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.ConfigurationInfo; import android.content.pm.IPackageDataObserver; import android.content.res.Configuration; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; Loading @@ -36,16 +36,17 @@ import android.os.Debug; import android.os.Handler; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserId; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; import android.view.Display; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; Loading Loading @@ -1798,6 +1799,40 @@ public class ActivityManager { } } /** @hide */ public static int checkComponentPermission(String permission, int uid, int owningUid, boolean exported) { // Root, system server get to do everything. if (uid == 0 || uid == Process.SYSTEM_UID) { return PackageManager.PERMISSION_GRANTED; } // Isolated processes don't get any permissions. if (UserId.isIsolated(uid)) { return PackageManager.PERMISSION_DENIED; } // If there is a uid that owns whatever is being accessed, it has // blanket access to it regardless of the permissions it requires. if (owningUid >= 0 && UserId.isSameApp(uid, owningUid)) { return PackageManager.PERMISSION_GRANTED; } // If the target is not exported, then nobody else can get to it. if (!exported) { Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid); return PackageManager.PERMISSION_DENIED; } if (permission == null) { return PackageManager.PERMISSION_GRANTED; } try { return AppGlobals.getPackageManager() .checkUidPermission(permission, uid); } catch (RemoteException e) { // Should never happen, but if it does... deny! Slog.e(TAG, "PackageManager is dead?!?", e); } return PackageManager.PERMISSION_DENIED; } /** * Returns the usage statistics of each installed package. * Loading
core/java/android/app/ActivityManagerNative.java +22 −0 Original line number Diff line number Diff line Loading @@ -1656,6 +1656,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } case GET_LAUNCHED_FROM_UID_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); int res = getLaunchedFromUid(token); reply.writeNoException(); reply.writeInt(res); return true; } } return super.onTransact(code, data, reply, flags); Loading Loading @@ -3785,5 +3794,18 @@ class ActivityManagerProxy implements IActivityManager return result; } public int getLaunchedFromUid(IBinder activityToken) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(activityToken); mRemote.transact(GET_LAUNCHED_FROM_UID_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); data.recycle(); reply.recycle(); return result; } private IBinder mRemote; }
core/java/android/app/IActivityManager.java +5 −0 Original line number Diff line number Diff line Loading @@ -350,6 +350,10 @@ public interface IActivityManager extends IInterface { public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent resultData) throws RemoteException; // This is not public because you need to be very careful in how you // manage your activity to make sure it is always the uid you expect. public int getLaunchedFromUid(IBinder activityToken) throws RemoteException; /* * Private non-Binder interfaces */ Loading Loading @@ -592,4 +596,5 @@ public interface IActivityManager extends IInterface { int NAVIGATE_UP_TO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+146; int SET_LOCK_SCREEN_SHOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+147; int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148; int GET_LAUNCHED_FROM_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+149; }
core/java/com/android/internal/app/ResolverActivity.java +57 −6 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import com.android.internal.R; import com.android.internal.content.PackageMonitor; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -34,6 +35,9 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.PatternMatcher; import android.os.Process; import android.os.RemoteException; import android.os.UserId; import android.util.Log; import android.view.LayoutInflater; import android.view.View; Loading Loading @@ -61,6 +65,7 @@ import java.util.Set; public class ResolverActivity extends AlertActivity implements AdapterView.OnItemClickListener { private static final String TAG = "ResolverActivity"; private int mLaunchedFromUid; private ResolveListAdapter mAdapter; private PackageManager mPm; private boolean mAlwaysUseOption; Loading Loading @@ -102,6 +107,12 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte boolean alwaysUseOption) { setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert); super.onCreate(savedInstanceState); try { mLaunchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid( getActivityToken()); } catch (RemoteException e) { mLaunchedFromUid = -1; } mPm = getPackageManager(); mAlwaysUseOption = alwaysUseOption; mMaxColumns = getResources().getInteger(R.integer.config_maxResolverActivityColumns); Loading @@ -118,9 +129,14 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte mIconDpi = am.getLauncherLargeIconDensity(); mIconSize = am.getLauncherLargeIconSize(); mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList); mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList, mLaunchedFromUid); int count = mAdapter.getCount(); if (count > 1) { if (mLaunchedFromUid < 0 || UserId.isIsolated(mLaunchedFromUid)) { // Gulp! finish(); return; } else if (count > 1) { ap.mView = getLayoutInflater().inflate(R.layout.resolver_grid, null); mGrid = (GridView) ap.mView.findViewById(R.id.resolver_grid); mGrid.setAdapter(mAdapter); Loading @@ -146,9 +162,13 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte if (alwaysUseOption) { final ViewGroup buttonLayout = (ViewGroup) findViewById(R.id.button_bar); if (buttonLayout != null) { buttonLayout.setVisibility(View.VISIBLE); mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always); mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once); } else { mAlwaysUseOption = false; } } } Loading Loading @@ -207,6 +227,18 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte mPackageMonitor.unregister(); mRegistered = false; } if ((getIntent().getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { // This resolver is in the unusual situation where it has been // launched at the top of a new task. We don't let it be added // to the recent tasks shown to the user, and we need to make sure // that each time we are launched we get the correct launching // uid (not re-using the same resolver from an old launching uid), // so we will now finish ourself since being no longer visible, // the user probably can't get back to us. if (!isChangingConfigurations()) { finish(); } } } @Override Loading Loading @@ -363,17 +395,19 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte private final Intent[] mInitialIntents; private final List<ResolveInfo> mBaseResolveList; private final Intent mIntent; private final int mLaunchedFromUid; private final LayoutInflater mInflater; private List<ResolveInfo> mCurrentResolveList; private List<DisplayResolveInfo> mList; public ResolveListAdapter(Context context, Intent intent, Intent[] initialIntents, List<ResolveInfo> rList) { Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid) { mIntent = new Intent(intent); mIntent.setComponent(null); mInitialIntents = initialIntents; mBaseResolveList = rList; mLaunchedFromUid = launchedFromUid; mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); rebuildList(); } Loading @@ -400,6 +434,23 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte mCurrentResolveList = mPm.queryIntentActivities( mIntent, PackageManager.MATCH_DEFAULT_ONLY | (mAlwaysUseOption ? PackageManager.GET_RESOLVED_FILTER : 0)); // Filter out any activities that the launched uid does not // have permission for. We don't do this when we have an explicit // list of resolved activities, because that only happens when // we are being subclassed, so we can safely launch whatever // they gave us. if (mCurrentResolveList != null) { for (int i=mCurrentResolveList.size()-1; i >= 0; i--) { ActivityInfo ai = mCurrentResolveList.get(i).activityInfo; int granted = ActivityManager.checkComponentPermission( ai.permission, mLaunchedFromUid, ai.applicationInfo.uid, ai.exported); if (granted != PackageManager.PERMISSION_GRANTED) { // Access not allowed! mCurrentResolveList.remove(i); } } } } int N; if ((mCurrentResolveList != null) && ((N = mCurrentResolveList.size()) > 0)) { Loading