diff options
Diffstat (limited to 'services')
3 files changed, 129 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index bb61149..b40882d 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1399,6 +1399,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59; static final int POST_PRIVACY_NOTIFICATION_MSG = 60; static final int CANCEL_PRIVACY_NOTIFICATION_MSG = 61; + static final int POST_COMPONENT_PROTECTED_MSG = 62; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -2167,6 +2168,69 @@ public final class ActivityManagerService extends ActivityManagerNative } catch (RemoteException e) { } } break; + case POST_COMPONENT_PROTECTED_MSG: { + INotificationManager inm = NotificationManager.getService(); + if (inm == null) { + return; + } + + Intent targetIntent = (Intent) msg.obj; + if (targetIntent == null) { + return; + } + + int targetUserId = targetIntent.getIntExtra( + "com.android.settings.PROTECTED_APPS_USER_ID", mCurrentUserId); + // Resolve for labels and whatnot + ActivityInfo root = resolveActivityInfo(targetIntent, targetIntent.getFlags(), + targetUserId); + + try { + Intent protectedAppIntent = new Intent(); + protectedAppIntent.setComponent( + new ComponentName("com.android.settings", + "com.android.settings.applications.ProtectedAppsActivity")); + protectedAppIntent.putExtra( + "com.android.settings.PROTECTED_APP_TARGET_INTENT", + targetIntent); + Context context = mContext.createPackageContext("com.android.settings", 0); + String title = mContext.getString( + com.android.internal.R.string + .notify_package_component_protected_title); + String text = mContext.getString( + com.android.internal.R.string + .notify_package_component_protected_text, + root.applicationInfo.loadLabel(mContext.getPackageManager())); + Notification notification = new Notification.Builder(context) + .setSmallIcon(com.android.internal.R.drawable.stat_notify_protected) + .setWhen(0) + .setTicker(title) + .setColor(mContext.getColor( + com.android.internal.R.color + .system_notification_accent_color)) + .setContentTitle(title) + .setContentText(text) + .setDefaults(Notification.DEFAULT_VIBRATE) + .setPriority(Notification.PRIORITY_MAX) + .setStyle(new Notification.BigTextStyle().bigText(text)) + .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, + protectedAppIntent, PendingIntent.FLAG_CANCEL_CURRENT, null, + new UserHandle(mCurrentUserId))) + .build(); + try { + int[] outId = new int[1]; + inm.enqueueNotificationWithTag("android", "android", null, + R.string.notify_package_component_protected_title, + notification, outId, mCurrentUserId); + } catch (RuntimeException e) { + Slog.w(ActivityManagerService.TAG, + "Error showing notification for protected app component", e); + } catch (RemoteException e) { + } + } catch (NameNotFoundException e) { + Slog.w(TAG, "Unable to create context for protected app notification", e); + } + } break; } } }; diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index be90dc8..cb281ec 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -971,6 +971,23 @@ public final class ActivityStackSupervisor implements DisplayListener { // Cannot start a child activity if the parent is not resumed. return ActivityManager.START_CANCELED; } + + try { + //TODO: This needs to be a flushed out API in the future. + if (AppGlobals.getPackageManager() + .isComponentProtected(callingPackage, intent.getComponent(), userId)) { + Message msg = mService.mHandler.obtainMessage( + ActivityManagerService.POST_COMPONENT_PROTECTED_MSG); + //Store start flags, userid + intent.setFlags(startFlags); + intent.putExtra("com.android.settings.PROTECTED_APPS_USER_ID", userId); + msg.obj = intent; + mService.mHandler.sendMessage(msg); + return ActivityManager.START_NOT_CURRENT_USER_ACTIVITY; + } + } catch (RemoteException e) { + e.printStackTrace(); + } final int realCallingPid = Binder.getCallingPid(); final int realCallingUid = Binder.getCallingUid(); int callingPid; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index c1fe38e..4987c9e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -336,6 +336,7 @@ public class PackageManagerService extends IPackageManager.Stub { private static final boolean DEBUG_DEXOPT = false; private static final boolean DEBUG_ABI_SELECTION = false; private static final boolean DEBUG_PREBUNDLED_SCAN = false; + private static final boolean DEBUG_PROTECTED = false; static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; @@ -17195,6 +17196,53 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override + public boolean isComponentProtected(String callingPackage, + ComponentName componentName, int userId) { + if (DEBUG_PROTECTED) Log.d(TAG, "Checking if component is protected " + + componentName.flattenToShortString() + " from calling package " + callingPackage); + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "set protected"); + + //Allow managers full access + List<String> protectedComponentManagers = + CMSettings.Secure.getDelimitedStringAsList(mContext.getContentResolver(), + CMSettings.Secure.PROTECTED_COMPONENT_MANAGERS, "|"); + if (protectedComponentManagers.contains(callingPackage)) { + if (DEBUG_PROTECTED) Log.d(TAG, "Calling package is a protected manager, allow"); + return false; + } + + String packageName = componentName.getPackageName(); + String className = componentName.getClassName(); + + //If this component is launched from the same package, allow it. + if (TextUtils.equals(packageName, callingPackage)) { + if (DEBUG_PROTECTED) Log.d(TAG, "Calling package is same as target, allow"); + return false; + } + + PackageSetting pkgSetting; + ArraySet<String> components; + + synchronized (mPackages) { + pkgSetting = mSettings.mPackages.get(packageName); + + if (pkgSetting == null) { + if (className == null) { + throw new IllegalArgumentException( + "Unknown package: " + packageName); + } + throw new IllegalArgumentException( + "Unknown component: " + packageName + + "/" + className); + } + // Get all the protected components + components = pkgSetting.getProtectedComponents(userId); + if (DEBUG_PROTECTED) Log.d(TAG, "Got " + components.size() + " protected components"); + return components.size() > 0; + } + } + + @Override public boolean isStorageLow() { final long token = Binder.clearCallingIdentity(); try { |