Merge "move away from MediaDebug and use ADebug instead for video editor engine"
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 4ed2489..cfc2d16 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -90,6 +90,7 @@
struct svcinfo *next;
void *ptr;
struct binder_death death;
+ int allow_isolated;
unsigned len;
uint16_t name[0];
};
@@ -125,13 +126,21 @@
};
-void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)
+void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len, unsigned uid)
{
struct svcinfo *si;
si = find_svc(s, len);
// ALOGI("check_service('%s') ptr = %p\n", str8(s), si ? si->ptr : 0);
if (si && si->ptr) {
+ if (!si->allow_isolated) {
+ // If this service doesn't allow access from isolated processes,
+ // then check the uid to see if it is isolated.
+ unsigned appid = uid % AID_USER;
+ if (appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END) {
+ return 0;
+ }
+ }
return si->ptr;
} else {
return 0;
@@ -140,10 +149,11 @@
int do_add_service(struct binder_state *bs,
uint16_t *s, unsigned len,
- void *ptr, unsigned uid)
+ void *ptr, unsigned uid, int allow_isolated)
{
struct svcinfo *si;
-// ALOGI("add_service('%s',%p) uid=%d\n", str8(s), ptr, uid);
+ //ALOGI("add_service('%s',%p,%s) uid=%d\n", str8(s), ptr,
+ // allow_isolated ? "allow_isolated" : "!allow_isolated", uid);
if (!ptr || (len == 0) || (len > 127))
return -1;
@@ -175,6 +185,7 @@
si->name[len] = '\0';
si->death.func = svcinfo_death;
si->death.ptr = si;
+ si->allow_isolated = allow_isolated;
si->next = svclist;
svclist = si;
}
@@ -194,6 +205,7 @@
unsigned len;
void *ptr;
uint32_t strict_policy;
+ int allow_isolated;
// ALOGI("target=%p code=%d pid=%d uid=%d\n",
// txn->target, txn->code, txn->sender_pid, txn->sender_euid);
@@ -217,7 +229,7 @@
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
- ptr = do_find_service(bs, s, len);
+ ptr = do_find_service(bs, s, len, txn->sender_euid);
if (!ptr)
break;
bio_put_ref(reply, ptr);
@@ -226,7 +238,8 @@
case SVC_MGR_ADD_SERVICE:
s = bio_get_string16(msg, &len);
ptr = bio_get_ref(msg);
- if (do_add_service(bs, s, len, ptr, txn->sender_euid))
+ allow_isolated = bio_get_uint32(msg) ? 1 : 0;
+ if (do_add_service(bs, s, len, ptr, txn->sender_euid, allow_isolated))
return -1;
break;
diff --git a/cmds/surfaceflinger/main_surfaceflinger.cpp b/cmds/surfaceflinger/main_surfaceflinger.cpp
index 78b1007..6dbcf5c 100644
--- a/cmds/surfaceflinger/main_surfaceflinger.cpp
+++ b/cmds/surfaceflinger/main_surfaceflinger.cpp
@@ -20,6 +20,6 @@
using namespace android;
int main(int argc, char** argv) {
- SurfaceFlinger::publishAndJoinThreadPool();
+ SurfaceFlinger::publishAndJoinThreadPool(true);
return 0;
}
diff --git a/core/java/android/os/IServiceManager.java b/core/java/android/os/IServiceManager.java
index 9a5ff47..7b11c28 100644
--- a/core/java/android/os/IServiceManager.java
+++ b/core/java/android/os/IServiceManager.java
@@ -45,7 +45,8 @@
* Place a new @a service called @a name into the service
* manager.
*/
- public void addService(String name, IBinder service) throws RemoteException;
+ public void addService(String name, IBinder service, boolean allowIsolated)
+ throws RemoteException;
/**
* Return a list of all currently running services.
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index 1af24f4a..13b8b66 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -69,7 +69,24 @@
*/
public static void addService(String name, IBinder service) {
try {
- getIServiceManager().addService(name, service);
+ getIServiceManager().addService(name, service, false);
+ } catch (RemoteException e) {
+ Log.e(TAG, "error in addService", e);
+ }
+ }
+
+ /**
+ * Place a new @a service called @a name into the service
+ * manager.
+ *
+ * @param name the name of the new service
+ * @param service the service object
+ * @param allowIsolated set to true to allow isolated sandboxed processes
+ * to access this service
+ */
+ public static void addService(String name, IBinder service, boolean allowIsolated) {
+ try {
+ getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 2aab0e6..43b5128 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -71,7 +71,8 @@
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = data.readStrongBinder();
- addService(name, service);
+ boolean allowIsolated = data.readInt() != 0;
+ addService(name, service, allowIsolated);
return true;
}
@@ -136,13 +137,14 @@
return binder;
}
- public void addService(String name, IBinder service)
+ public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
+ data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
diff --git a/core/java/android/os/UserId.java b/core/java/android/os/UserId.java
index 4124d51..286b674 100644
--- a/core/java/android/os/UserId.java
+++ b/core/java/android/os/UserId.java
@@ -56,6 +56,11 @@
return getAppId(uid1) == getAppId(uid2);
}
+ public static final boolean isIsolated(int uid) {
+ uid = getAppId(uid);
+ return uid >= Process.FIRST_ISOLATED_UID && uid <= Process.LAST_ISOLATED_UID;
+ }
+
/**
* Returns the user id for a given uid.
* @hide
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 97658a1..1199cf7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -717,6 +717,13 @@
android:label="@string/permlab_removeTasks"
android:description="@string/permdesc_removeTasks" />
+ <!-- @hide Change the screen compatibility mode of applications -->
+ <permission android:name="android.permission.SET_SCREEN_COMPATIBILITY"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signature"
+ android:label="@string/permlab_setScreenCompatibility"
+ android:description="@string/permdesc_setScreenCompatibility" />
+
<!-- Allows an application to modify the current configuration, such
as locale. -->
<permission android:name="android.permission.CHANGE_CONFIGURATION"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index dc45c408..701782c 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -532,6 +532,13 @@
tasks and kill their apps. Malicious apps may disrupt
the behavior of other apps.</string>
+ <!-- Title of an application permission, allowing control of app screen compatibility mode -->
+ <string name="permlab_setScreenCompatibility">set screen compatibility</string>
+ <!-- Description of an application permission, allowing control of app screen compatibility mode -->
+ <string name="permdesc_setScreenCompatibility">Allows the app to control the
+ screen compatibility mode of other applications. Malicious applications may
+ break the behavior of other applications.</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_setDebugApp">enable app debugging</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/include/binder/BinderService.h b/include/binder/BinderService.h
index 2316fef..ca594d3 100644
--- a/include/binder/BinderService.h
+++ b/include/binder/BinderService.h
@@ -34,15 +34,15 @@
class BinderService
{
public:
- static status_t publish() {
+ static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
- return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
+ return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
}
- static void publishAndJoinThreadPool() {
+ static void publishAndJoinThreadPool(bool allowIsolated = false) {
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
- sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
+ sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
diff --git a/include/binder/IServiceManager.h b/include/binder/IServiceManager.h
index 24e9e99..2c297d6 100644
--- a/include/binder/IServiceManager.h
+++ b/include/binder/IServiceManager.h
@@ -47,7 +47,8 @@
* Register a service.
*/
virtual status_t addService( const String16& name,
- const sp<IBinder>& service) = 0;
+ const sp<IBinder>& service,
+ bool allowIsolated = false) = 0;
/**
* Return list of all existing services.
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 33b305d..1750640 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -151,12 +151,14 @@
return reply.readStrongBinder();
}
- virtual status_t addService(const String16& name, const sp<IBinder>& service)
+ virtual status_t addService(const String16& name, const sp<IBinder>& service,
+ bool allowIsolated)
{
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
+ data.writeInt32(allowIsolated ? 1 : 0);
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 10a0efe..a110dd6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2093,7 +2093,7 @@
try {
ActivityManagerService m = mSelf;
- ServiceManager.addService("activity", m);
+ ServiceManager.addService("activity", m, true);
ServiceManager.addService("meminfo", new MemBinder(m));
ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
ServiceManager.addService("dbinfo", new DbBinder(m));
@@ -2964,37 +2964,52 @@
return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
}
+ void enforceNotIsolatedCaller(String caller) {
+ if (UserId.isIsolated(Binder.getCallingUid())) {
+ throw new SecurityException("Isolated process not allowed to call " + caller);
+ }
+ }
+
public int getFrontActivityScreenCompatMode() {
+ enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
synchronized (this) {
return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
}
}
public void setFrontActivityScreenCompatMode(int mode) {
+ enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+ "setFrontActivityScreenCompatMode");
synchronized (this) {
mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
}
}
public int getPackageScreenCompatMode(String packageName) {
+ enforceNotIsolatedCaller("getPackageScreenCompatMode");
synchronized (this) {
return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
}
}
public void setPackageScreenCompatMode(String packageName, int mode) {
+ enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+ "setPackageScreenCompatMode");
synchronized (this) {
mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
}
}
public boolean getPackageAskScreenCompat(String packageName) {
+ enforceNotIsolatedCaller("getPackageAskScreenCompat");
synchronized (this) {
return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
}
}
public void setPackageAskScreenCompat(String packageName, boolean ask) {
+ enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+ "setPackageAskScreenCompat");
synchronized (this) {
mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
}
@@ -3069,6 +3084,7 @@
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
+ enforceNotIsolatedCaller("startActivity");
int userId = 0;
if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
// Requesting home, set the identity to the current user
@@ -3093,6 +3109,7 @@
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
+ enforceNotIsolatedCaller("startActivityAndWait");
WaitResult res = new WaitResult();
int userId = Binder.getOrigCallingUser();
mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
@@ -3107,6 +3124,7 @@
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded,
boolean debug, Configuration config) {
+ enforceNotIsolatedCaller("startActivityWithConfig");
int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded,
@@ -3118,6 +3136,7 @@
IntentSender intent, Intent fillInIntent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode,
int flagsMask, int flagsValues) {
+ enforceNotIsolatedCaller("startActivityIntentSender");
// Refuse possible leaked file descriptors
if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -3259,6 +3278,7 @@
public final int startActivities(IApplicationThread caller,
Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
+ enforceNotIsolatedCaller("startActivities");
int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
Binder.getOrigCallingUser());
return ret;
@@ -4020,6 +4040,7 @@
public boolean clearApplicationUserData(final String packageName,
final IPackageDataObserver observer, final int userId) {
+ enforceNotIsolatedCaller("clearApplicationUserData");
int uid = Binder.getCallingUid();
int pid = Binder.getCallingPid();
long callingId = Binder.clearCallingIdentity();
@@ -4208,6 +4229,7 @@
}
public void closeSystemDialogs(String reason) {
+ enforceNotIsolatedCaller("closeSystemDialogs");
Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
if (reason != null) {
@@ -4248,6 +4270,7 @@
public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
throws RemoteException {
+ enforceNotIsolatedCaller("getProcessMemoryInfo");
Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
for (int i=pids.length-1; i>=0; i--) {
infos[i] = new Debug.MemoryInfo();
@@ -4257,6 +4280,7 @@
}
public long[] getProcessPss(int[] pids) throws RemoteException {
+ enforceNotIsolatedCaller("getProcessPss");
long[] pss = new long[pids.length];
for (int i=pids.length-1; i>=0; i--) {
pss[i] = Debug.getPss(pids[i]);
@@ -4825,10 +4849,12 @@
}
public void showBootMessage(final CharSequence msg, final boolean always) {
+ enforceNotIsolatedCaller("showBootMessage");
mWindowManager.showBootMessage(msg, always);
}
public void dismissKeyguardOnNextActivity() {
+ enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
synchronized (this) {
mMainStack.dismissKeyguardOnNextActivityLocked();
}
@@ -4991,6 +5017,7 @@
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
+ enforceNotIsolatedCaller("getIntentSender");
// Refuse possible leaked file descriptors
if (intents != null) {
if (intents.length < 1) {
@@ -5293,6 +5320,10 @@
if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
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)) {
@@ -5445,6 +5476,8 @@
}
public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
+ enforceNotIsolatedCaller("checkUriPermission");
+
// Another redirected-binder-call permissions check as in
// {@link checkComponentPermission}.
Identity tlsIdentity = sCallerIdentity.get();
@@ -5595,6 +5628,7 @@
public int checkGrantUriPermission(int callingUid, String targetPkg,
Uri uri, int modeFlags) {
+ enforceNotIsolatedCaller("checkGrantUriPermission");
synchronized(this) {
return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
}
@@ -5703,6 +5737,7 @@
public void grantUriPermission(IApplicationThread caller, String targetPkg,
Uri uri, int modeFlags) {
+ enforceNotIsolatedCaller("grantUriPermission");
synchronized(this) {
final ProcessRecord r = getRecordForAppLocked(caller);
if (r == null) {
@@ -5826,6 +5861,7 @@
public void revokeUriPermission(IApplicationThread caller, Uri uri,
int modeFlags) {
+ enforceNotIsolatedCaller("revokeUriPermission");
synchronized(this) {
final ProcessRecord r = getRecordForAppLocked(caller);
if (r == null) {
@@ -5870,6 +5906,7 @@
@Override
public IBinder newUriPermissionOwner(String name) {
+ enforceNotIsolatedCaller("newUriPermissionOwner");
synchronized(this) {
UriPermissionOwner owner = new UriPermissionOwner(this, name);
return owner.getExternalTokenLocked();
@@ -6406,6 +6443,7 @@
* @return Returns true if the move completed, false if not.
*/
public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
+ enforceNotIsolatedCaller("moveActivityTaskToBack");
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
int taskId = getTaskForActivityLocked(token, !nonRoot);
@@ -6460,6 +6498,7 @@
}
public void finishOtherInstances(IBinder token, ComponentName className) {
+ enforceNotIsolatedCaller("finishOtherInstances");
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
@@ -6938,6 +6977,7 @@
public final ContentProviderHolder getContentProvider(
IApplicationThread caller, String name) {
+ enforceNotIsolatedCaller("getContentProvider");
if (caller == null) {
String msg = "null IApplicationThread when getting content provider "
+ name;
@@ -6958,6 +6998,7 @@
* @param cpr
*/
public void removeContentProvider(IApplicationThread caller, String name) {
+ enforceNotIsolatedCaller("removeContentProvider");
synchronized (this) {
int userId = UserId.getUserId(Binder.getCallingUid());
ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
@@ -7020,6 +7061,7 @@
return;
}
+ enforceNotIsolatedCaller("publishContentProviders");
synchronized(this) {
final ProcessRecord r = getRecordForAppLocked(caller);
if (DEBUG_MU)
@@ -7107,6 +7149,7 @@
* src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
*/
public String getProviderMimeType(Uri uri) {
+ enforceNotIsolatedCaller("getProviderMimeType");
final String name = uri.getAuthority();
final long ident = Binder.clearCallingIdentity();
ContentProviderHolder holder = null;
@@ -7224,6 +7267,7 @@
}
public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
+ enforceNotIsolatedCaller("openContentUri");
String name = uri.getAuthority();
ContentProviderHolder cph = getContentProviderExternal(name);
ParcelFileDescriptor pfd = null;
@@ -7477,6 +7521,7 @@
}
public void registerActivityWatcher(IActivityWatcher watcher) {
+ enforceNotIsolatedCaller("registerActivityWatcher");
synchronized (this) {
mWatchers.register(watcher);
}
@@ -7489,6 +7534,7 @@
}
public void registerProcessObserver(IProcessObserver observer) {
+ enforceNotIsolatedCaller("registerProcessObserver");
mProcessObservers.register(observer);
}
@@ -7517,6 +7563,7 @@
}
public boolean isTopActivityImmersive() {
+ enforceNotIsolatedCaller("startActivity");
synchronized (this) {
ActivityRecord r = mMainStack.topRunningActivityLocked(null);
return (r != null) ? r.immersive : false;
@@ -8701,6 +8748,7 @@
}
public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
+ enforceNotIsolatedCaller("getProcessesInErrorState");
// assume our apps are happy - lazy create the list
List<ActivityManager.ProcessErrorStateInfo> errList = null;
@@ -8763,6 +8811,7 @@
}
public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
+ enforceNotIsolatedCaller("getRunningAppProcesses");
// Lazy instantiation of list
List<ActivityManager.RunningAppProcessInfo> runList = null;
synchronized (this) {
@@ -8808,6 +8857,7 @@
}
public List<ApplicationInfo> getRunningExternalApplications() {
+ enforceNotIsolatedCaller("getRunningExternalApplications");
List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
if (runningApps != null && runningApps.size() > 0) {
@@ -11323,6 +11373,7 @@
public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
int flags) {
+ enforceNotIsolatedCaller("getServices");
synchronized (this) {
ArrayList<ActivityManager.RunningServiceInfo> res
= new ArrayList<ActivityManager.RunningServiceInfo>();
@@ -11349,6 +11400,7 @@
}
public PendingIntent getRunningServiceControlPanel(ComponentName name) {
+ enforceNotIsolatedCaller("getRunningServiceControlPanel");
synchronized (this) {
int userId = UserId.getUserId(Binder.getCallingUid());
ServiceRecord r = mServiceMap.getServiceByName(name, userId);
@@ -12076,6 +12128,7 @@
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType) {
+ enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -12118,6 +12171,7 @@
public int stopService(IApplicationThread caller, Intent service,
String resolvedType) {
+ enforceNotIsolatedCaller("stopService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -12155,6 +12209,7 @@
}
public IBinder peekService(Intent service, String resolvedType) {
+ enforceNotIsolatedCaller("peekService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -12293,6 +12348,7 @@
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags) {
+ enforceNotIsolatedCaller("bindService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -12949,6 +13005,7 @@
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission) {
+ enforceNotIsolatedCaller("registerReceiver");
synchronized(this) {
ProcessRecord callerApp = null;
if (caller != null) {
@@ -13458,6 +13515,7 @@
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, boolean serialized, boolean sticky, int userId) {
+ enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
intent = verifyBroadcastLocked(intent);
@@ -13704,6 +13762,7 @@
public boolean startInstrumentation(ComponentName className,
String profileFile, int flags, Bundle arguments,
IInstrumentationWatcher watcher) {
+ enforceNotIsolatedCaller("startInstrumentation");
// Refuse possible leaked file descriptors
if (arguments != null && arguments.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Bundle");
@@ -13901,7 +13960,7 @@
* configuration.
* @param persistent TODO
*/
- public boolean updateConfigurationLocked(Configuration values,
+ boolean updateConfigurationLocked(Configuration values,
ActivityRecord starting, boolean persistent, boolean initLocale) {
int changes = 0;
@@ -15321,7 +15380,7 @@
synchronized (this) { }
}
- public void onCoreSettingsChange(Bundle settings) {
+ void onCoreSettingsChange(Bundle settings) {
for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
ProcessRecord processRecord = mLruProcesses.get(i);
try {
diff --git a/tests/BiDiTests/res/layout/grid_layout_code.xml b/tests/BiDiTests/res/layout/grid_layout_code.xml
new file mode 100644
index 0000000..87a0ec0
--- /dev/null
+++ b/tests/BiDiTests/res/layout/grid_layout_code.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/grid_layout_code"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
index 4d7ace1..c5a1235 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
@@ -111,6 +111,8 @@
addItem(result, "Grid LTR", BiDiTestGridLayoutLtr.class, R.id.grid_layout_ltr);
addItem(result, "Grid RTL", BiDiTestGridLayoutRtl.class, R.id.grid_layout_rtl);
addItem(result, "Grid LOC", BiDiTestGridLayoutLocale.class, R.id.grid_layout_locale);
+ addItem(result, "Grid C-LTR", BiDiTestGridLayoutCodeLtr.class, R.id.grid_layout_code);
+ addItem(result, "Grid C-RTL", BiDiTestGridLayoutCodeRtl.class, R.id.grid_layout_code);
addItem(result, "Frame LTR", BiDiTestFrameLayoutLtr.class, R.id.frame_layout_ltr);
addItem(result, "Frame RTL", BiDiTestFrameLayoutRtl.class, R.id.frame_layout_rtl);
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
new file mode 100644
index 0000000..859b8fb
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bidi;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.GridLayout;
+
+import android.widget.*;
+
+import static android.text.InputType.*;
+import static android.widget.GridLayout.*;
+
+public class BiDiTestGridLayoutCodeLtr extends Fragment {
+
+ private FrameLayout currentView;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ currentView = (FrameLayout) inflater.inflate(R.layout.grid_layout_code, container, false);
+ return currentView;
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ currentView.addView(create(currentView.getContext()));
+ }
+
+ public static View create(Context context) {
+ GridLayout layout = new GridLayout(context);
+ layout.setUseDefaultMargins(true);
+ layout.setAlignmentMode(ALIGN_BOUNDS);
+ layout.setRowOrderPreserved(false);
+ layout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
+
+ Spec row1 = spec(0);
+ Spec row2 = spec(1);
+ Spec row3 = spec(2, BASELINE);
+ Spec row4 = spec(3, BASELINE);
+ Spec row5 = spec(2, 3, FILL); // allow the last two rows to overlap the middle two
+ Spec row6 = spec(5);
+ Spec row7 = spec(6);
+
+ Spec col1a = spec(0, 4, CENTER);
+ Spec col1b = spec(0, 4, START);
+ Spec col1c = spec(0, END);
+ Spec col2 = spec(1, START);
+ Spec col3 = spec(2, FILL);
+ Spec col4a = spec(3);
+ Spec col4b = spec(3, FILL);
+
+ {
+ TextView c = new TextView(context);
+ c.setTextSize(32);
+ c.setText("Email setup");
+ layout.addView(c, new GridLayout.LayoutParams(row1, col1a));
+ }
+ {
+ TextView c = new TextView(context);
+ c.setTextSize(16);
+ c.setText("You can configure email in just a few steps:");
+ layout.addView(c, new GridLayout.LayoutParams(row2, col1b));
+ }
+ {
+ TextView c = new TextView(context);
+ c.setText("Email address:");
+ layout.addView(c, new GridLayout.LayoutParams(row3, col1c));
+ }
+ {
+ EditText c = new EditText(context);
+ c.setEms(10);
+ c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
+ layout.addView(c, new GridLayout.LayoutParams(row3, col2));
+ }
+ {
+ TextView c = new TextView(context);
+ c.setText("Password:");
+ layout.addView(c, new GridLayout.LayoutParams(row4, col1c));
+ }
+ {
+ TextView c = new EditText(context);
+ c.setEms(8);
+ c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD);
+ layout.addView(c, new GridLayout.LayoutParams(row4, col2));
+ }
+ {
+ Space c = new Space(context);
+ layout.addView(c, new GridLayout.LayoutParams(row5, col3));
+ }
+ {
+ Button c = new Button(context);
+ c.setText("Manual setup");
+ layout.addView(c, new GridLayout.LayoutParams(row6, col4a));
+ }
+ {
+ Button c = new Button(context);
+ c.setText("Next");
+ layout.addView(c, new GridLayout.LayoutParams(row7, col4b));
+ }
+
+ return layout;
+ }
+}
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
new file mode 100644
index 0000000..fac8c95
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bidi;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.*;
+
+import static android.text.InputType.*;
+import static android.widget.GridLayout.*;
+
+public class BiDiTestGridLayoutCodeRtl extends Fragment {
+
+ private FrameLayout currentView;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ currentView = (FrameLayout) inflater.inflate(R.layout.grid_layout_code, container, false);
+ return currentView;
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ currentView.addView(create(currentView.getContext()));
+ }
+
+ public static View create(Context context) {
+ GridLayout layout = new GridLayout(context);
+ layout.setUseDefaultMargins(true);
+ layout.setAlignmentMode(ALIGN_BOUNDS);
+ layout.setRowOrderPreserved(false);
+ layout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+
+ Spec row1 = spec(0);
+ Spec row2 = spec(1);
+ Spec row3 = spec(2, BASELINE);
+ Spec row4 = spec(3, BASELINE);
+ Spec row5 = spec(2, 3, FILL); // allow the last two rows to overlap the middle two
+ Spec row6 = spec(5);
+ Spec row7 = spec(6);
+
+ Spec col1a = spec(0, 4, CENTER);
+ Spec col1b = spec(0, 4, START);
+ Spec col1c = spec(0, END);
+ Spec col2 = spec(1, START);
+ Spec col3 = spec(2, FILL);
+ Spec col4a = spec(3);
+ Spec col4b = spec(3, FILL);
+
+ {
+ TextView c = new TextView(context);
+ c.setTextSize(32);
+ c.setText("Email setup");
+ layout.addView(c, new GridLayout.LayoutParams(row1, col1a));
+ }
+ {
+ TextView c = new TextView(context);
+ c.setTextSize(16);
+ c.setText("You can configure email in just a few steps:");
+ layout.addView(c, new GridLayout.LayoutParams(row2, col1b));
+ }
+ {
+ TextView c = new TextView(context);
+ c.setText("Email address:");
+ layout.addView(c, new GridLayout.LayoutParams(row3, col1c));
+ }
+ {
+ EditText c = new EditText(context);
+ c.setEms(10);
+ c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
+ layout.addView(c, new GridLayout.LayoutParams(row3, col2));
+ }
+ {
+ TextView c = new TextView(context);
+ c.setText("Password:");
+ layout.addView(c, new GridLayout.LayoutParams(row4, col1c));
+ }
+ {
+ TextView c = new EditText(context);
+ c.setEms(8);
+ c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD);
+ layout.addView(c, new GridLayout.LayoutParams(row4, col2));
+ }
+ {
+ Space c = new Space(context);
+ layout.addView(c, new GridLayout.LayoutParams(row5, col3));
+ }
+ {
+ Button c = new Button(context);
+ c.setText("Manual setup");
+ layout.addView(c, new GridLayout.LayoutParams(row6, col4a));
+ }
+ {
+ Button c = new Button(context);
+ c.setText("Next");
+ layout.addView(c, new GridLayout.LayoutParams(row7, col4b));
+ }
+
+ return layout;
+ }
+}