Fixes #1963229. Introduces Context#isRestricted().
A restricted Context is a special type of Context that prevents specific features from being used. For instance, android:onClick, used by View, can be dangerous when used from within apps widgets. By using a restricted Context to inflate apps widgets, widgets providers are prevented from using android:onClick.
This commit is contained in:
@@ -184,6 +184,7 @@ class ApplicationContext extends Context {
|
||||
private StatusBarManager mStatusBarManager = null;
|
||||
private TelephonyManager mTelephonyManager = null;
|
||||
private ClipboardManager mClipboardManager = null;
|
||||
private boolean mRestricted;
|
||||
|
||||
private final Object mSync = new Object();
|
||||
|
||||
@@ -1336,6 +1337,7 @@ class ApplicationContext extends Context {
|
||||
mMainThread.getPackageInfo(packageName, flags);
|
||||
if (pi != null) {
|
||||
ApplicationContext c = new ApplicationContext();
|
||||
c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
|
||||
c.init(pi, null, mMainThread);
|
||||
if (c.mResources != null) {
|
||||
return c;
|
||||
@@ -1347,6 +1349,11 @@ class ApplicationContext extends Context {
|
||||
"Application package " + packageName + " not found");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRestricted() {
|
||||
return mRestricted;
|
||||
}
|
||||
|
||||
private File getDataDirFile() {
|
||||
if (mPackageInfo != null) {
|
||||
return mPackageInfo.getDataDirFile();
|
||||
|
||||
@@ -269,7 +269,7 @@ public class AppWidgetHostView extends FrameLayout {
|
||||
try {
|
||||
if (mInfo != null) {
|
||||
Context theirContext = mContext.createPackageContext(
|
||||
mInfo.provider.getPackageName(), 0 /* no flags */);
|
||||
mInfo.provider.getPackageName(), Context.CONTEXT_RESTRICTED);
|
||||
LayoutInflater inflater = (LayoutInflater)
|
||||
theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
inflater = inflater.cloneInContext(theirContext);
|
||||
|
||||
@@ -1654,6 +1654,13 @@ public abstract class Context {
|
||||
* with extreme care!
|
||||
*/
|
||||
public static final int CONTEXT_IGNORE_SECURITY = 0x00000002;
|
||||
|
||||
/**
|
||||
* Flag for use with {@link #createPackageContext}: a restricted context may
|
||||
* disable specific features. For instance, a View associated with a restricted
|
||||
* context would ignore particular XML attributes.
|
||||
*/
|
||||
public static final int CONTEXT_RESTRICTED = 0x00000004;
|
||||
|
||||
/**
|
||||
* Return a new Context object for the given application name. This
|
||||
@@ -1682,4 +1689,15 @@ public abstract class Context {
|
||||
*/
|
||||
public abstract Context createPackageContext(String packageName,
|
||||
int flags) throws PackageManager.NameNotFoundException;
|
||||
|
||||
/**
|
||||
* Indicates whether this Context is restricted.
|
||||
*
|
||||
* @return True if this Context is restricted, false otherwise.
|
||||
*
|
||||
* @see #CONTEXT_RESTRICTED
|
||||
*/
|
||||
public boolean isRestricted() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,4 +430,9 @@ public class ContextWrapper extends Context {
|
||||
throws PackageManager.NameNotFoundException {
|
||||
return mBase.createPackageContext(packageName, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRestricted() {
|
||||
return mBase.isRestricted();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1996,6 +1996,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
mMinHeight = a.getDimensionPixelSize(attr, 0);
|
||||
break;
|
||||
case R.styleable.View_onClick:
|
||||
if (context.isRestricted()) {
|
||||
throw new IllegalStateException("The android:onClick attribute cannot "
|
||||
+ "be used within a restricted context");
|
||||
}
|
||||
|
||||
final String handlerName = a.getString(attr);
|
||||
if (handlerName != null) {
|
||||
setOnClickListener(new OnClickListener() {
|
||||
|
||||
@@ -856,7 +856,7 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
|
||||
if (packageName != null) {
|
||||
try {
|
||||
c = context.createPackageContext(packageName, 0);
|
||||
c = context.createPackageContext(packageName, Context.CONTEXT_RESTRICTED);
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(LOG_TAG, "Package name " + packageName + " not found");
|
||||
c = context;
|
||||
|
||||
Reference in New Issue
Block a user