diff options
| author | Steve Kondik <shade@chemlab.org> | 2013-06-12 00:47:55 -0700 |
|---|---|---|
| committer | Steve Kondik <shade@chemlab.org> | 2013-06-24 11:36:22 -0700 |
| commit | e48fce6da7bd839d70cbf69abb2780c6d30ea7f6 (patch) | |
| tree | 49dd160f5a5d10847fd446e0db7f31f2d800792f /core | |
| parent | b429a08331e8ebea15113fe287f4e5c9478d7001 (diff) | |
| download | frameworks_base-e48fce6da7bd839d70cbf69abb2780c6d30ea7f6.zip frameworks_base-e48fce6da7bd839d70cbf69abb2780c6d30ea7f6.tar.gz frameworks_base-e48fce6da7bd839d70cbf69abb2780c6d30ea7f6.tar.bz2 | |
framework: Privacy Guard
* Introduce a new privacy feature which allows the user to run an
application with reduced visibility into his or her personal data.
* Adds a per-application flag and simple API to determine if this flag
is enabled for the current or calling process.
* This flag can be used by content providers to decide if they should
return a limited/empty dataset.
Change-Id: Id7c54d728e63acb2b02a2a9322930b54949f6c5d
Diffstat (limited to 'core')
18 files changed, 175 insertions, 3 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 61b2067..b4cc515 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1818,6 +1818,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case IS_PRIVACY_GUARD_ENABLED_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + int pid = data.readInt(); + boolean res = isPrivacyGuardEnabledForProcess(pid); + reply.writeNoException(); + reply.writeInt(res ? 1 : 0); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -4149,5 +4157,17 @@ class ActivityManagerProxy implements IActivityManager return res; } + public boolean isPrivacyGuardEnabledForProcess(int pid) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(pid); + mRemote.transact(IS_PRIVACY_GUARD_ENABLED_TRANSACTION, data, reply, 0); + reply.readException(); + int res = reply.readInt(); + data.recycle(); + reply.recycle(); + return res == 1; + } private IBinder mRemote; } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 0d11e29..aa7d98c 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -48,6 +48,7 @@ import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Binder; import android.os.Process; import android.os.RemoteException; import android.util.Log; @@ -1296,6 +1297,25 @@ final class ApplicationPackageManager extends PackageManager { return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; } + @Override + public void setPrivacyGuardSetting(String packageName, boolean enabled) { + try { + mPM.setPrivacyGuardSetting(packageName, enabled, mContext.getUserId()); + } catch (RemoteException e) { + // Should never happen! + } + } + + @Override + public boolean getPrivacyGuardSetting(String packageName) { + try { + return mPM.getPrivacyGuardSetting(packageName, mContext.getUserId()); + } catch (RemoteException e) { + // Should never happen! + } + return false; + } + /** * @hide */ diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 4d9f11e..21fbc1f 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1550,6 +1550,16 @@ class ContextImpl extends Context { } @Override + public boolean isPrivacyGuardEnabled() { + try { + return ActivityManagerNative.getDefault().isPrivacyGuardEnabledForProcess(Binder.getCallingPid()); + } catch (RemoteException e) { + Log.e(TAG, e.getMessage(), e); + } + return false; + } + + @Override public int checkPermission(String permission, int pid, int uid) { if (permission == null) { throw new IllegalArgumentException("permission is null"); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 8af17a4..4d04e68 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -190,7 +190,9 @@ public interface IActivityManager extends IInterface { public void setProcessForeground(IBinder token, int pid, boolean isForeground) throws RemoteException; - + + public boolean isPrivacyGuardEnabledForProcess(int pid) throws RemoteException; + public int checkPermission(String permission, int pid, int uid) throws RemoteException; @@ -624,4 +626,5 @@ public interface IActivityManager extends IInterface { int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158; int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159; int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160; + int IS_PRIVACY_GUARD_ENABLED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index f0c6ce8..bd7868f 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2267,6 +2267,16 @@ public abstract class Context { public static final String USER_SERVICE = "user"; /** + * Determine whether the application or calling application has + * privacy guard. This is a privacy feature intended to permit the user + * to control access to personal data. Applications and content providers + * can check this value if they wish to honor privacy guard. + * + * @hide + */ + public abstract boolean isPrivacyGuardEnabled(); + + /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. * diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 84ad667..3f61075 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -496,6 +496,11 @@ public class ContextWrapper extends Context { } @Override + public boolean isPrivacyGuardEnabled() { + return mBase.isPrivacyGuardEnabled(); + } + + @Override public int checkPermission(String permission, int pid, int uid) { return mBase.checkPermission(permission, pid, uid); } diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index d6a78ea..a5accc6 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -212,7 +212,11 @@ interface IPackageManager { int getPreferredActivities(out List<IntentFilter> outFilters, out List<ComponentName> outActivities, String packageName); - + + boolean getPrivacyGuardSetting(in String packageName, int userId); + + void setPrivacyGuardSetting(in String packageName, boolean enabled, int userId); + /** * As per {@link android.content.pm.PackageManager#setComponentEnabledSetting}. */ diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index eb6e640..28d60c8 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2941,6 +2941,22 @@ public abstract class PackageManager { public abstract int getApplicationEnabledSetting(String packageName); /** + * @param packageName + * @return + * + * @hide + */ + public abstract boolean getPrivacyGuardSetting(String packageName); + + /** + * @param packageName + * @param enabled + * + * @hide + */ + public abstract void setPrivacyGuardSetting(String packageName, boolean enabled); + + /** * Return whether the device has been booted into safe mode. */ public abstract boolean isSafeMode(); diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java index 3579977..91ef1bc 100644 --- a/core/java/android/content/pm/PackageUserState.java +++ b/core/java/android/content/pm/PackageUserState.java @@ -29,6 +29,7 @@ public class PackageUserState { public boolean notLaunched; public boolean installed; public int enabled; + public boolean privacyGuard; public HashSet<String> disabledComponents; public HashSet<String> enabledComponents; @@ -36,6 +37,7 @@ public class PackageUserState { public PackageUserState() { installed = true; enabled = COMPONENT_ENABLED_STATE_DEFAULT; + privacyGuard = false; } public PackageUserState(PackageUserState o) { @@ -43,6 +45,7 @@ public class PackageUserState { stopped = o.stopped; notLaunched = o.notLaunched; enabled = o.enabled; + privacyGuard = o.privacyGuard; disabledComponents = o.disabledComponents != null ? new HashSet<String>(o.disabledComponents) : null; enabledComponents = o.enabledComponents != null diff --git a/core/java/android/database/MemoryCursor.java b/core/java/android/database/MemoryCursor.java new file mode 100644 index 0000000..7eb71db --- /dev/null +++ b/core/java/android/database/MemoryCursor.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 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 android.database; + +import android.database.AbstractWindowedCursor; +import android.database.Cursor; +import android.database.CursorWindow; +import android.database.DatabaseUtils; + +/** + * Implementation of an in-memory cursor backed by a cursor window. + * + * @hide + */ +public class MemoryCursor extends AbstractWindowedCursor { + + private final String[] mColumnNames; + + public MemoryCursor(String name, String[] columnNames) { + setWindow(new CursorWindow(name)); + mColumnNames = columnNames; + } + + public void fillFromCursor(Cursor cursor) { + DatabaseUtils.cursorFillWindow(cursor, 0, getWindow()); + } + + @Override + public int getCount() { + return getWindow().getNumRows(); + } + + @Override + public String[] getColumnNames() { + return mColumnNames; + } +} diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 90b9b32..22fa2fa 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -18,6 +18,7 @@ package android.provider; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.app.ActivityManagerNative; import android.app.SearchManager; import android.app.WallpaperManager; import android.content.ComponentName; @@ -37,6 +38,7 @@ import android.net.ConnectivityManager; import android.net.Uri; import android.net.wifi.WifiManager; import android.os.BatteryManager; +import android.os.Binder; import android.os.Bundle; import android.os.DropBoxManager; import android.os.IBinder; @@ -5021,6 +5023,12 @@ public final class Settings { public static final String ADVANCED_REBOOT = "advanced_reboot"; /** + * Whether newly installed apps should run with privacy guard by default + * @hide + */ + public static final String PRIVACY_GUARD_DEFAULT = "privacy_guard_default"; + + /** * This are the settings to be backed up. * * NOTE: Settings are backed up and restored in the order they appear @@ -5063,7 +5071,8 @@ public final class Settings { UI_NIGHT_MODE, LOCK_SCREEN_OWNER_INFO, LOCK_SCREEN_OWNER_INFO_ENABLED, - ADVANCED_REBOOT + ADVANCED_REBOOT, + PRIVACY_GUARD_DEFAULT }; /** @@ -5085,6 +5094,13 @@ public final class Settings { * @hide */ public static final boolean isLocationProviderEnabledForUser(ContentResolver cr, String provider, int userId) { + try { + if (ActivityManagerNative.getDefault().isPrivacyGuardEnabledForProcess(Binder.getCallingPid())) { + return false; + } + } catch (RemoteException e) { + // ignore + } String allowedProviders = Settings.Secure.getStringForUser(cr, LOCATION_PROVIDERS_ALLOWED, userId); return TextUtils.delimitedStringContains(allowedProviders, ',', provider); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 373d018..bac9ff6 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1856,6 +1856,12 @@ android:description="@string/permdesc_movePackage" android:protectionLevel="signature|system" /> + <!-- Allows an application to change privacy guard state --> + <permission android:name="android.permission.CHANGE_PRIVACY_GUARD_STATE" + android:label="@string/permlab_changePrivacyGuardState" + android:description="@string/permdesc_changePrivacyGuardState" + android:protectionLevel="signature" /> + <!-- Allows an application to change whether an application component (other than its own) is enabled or not. --> <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" diff --git a/core/res/res/drawable-hdpi/stat_notify_privacy_guard.png b/core/res/res/drawable-hdpi/stat_notify_privacy_guard.png Binary files differnew file mode 100644 index 0000000..ac7f817 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_notify_privacy_guard.png diff --git a/core/res/res/drawable-mdpi/stat_notify_privacy_guard.png b/core/res/res/drawable-mdpi/stat_notify_privacy_guard.png Binary files differnew file mode 100644 index 0000000..0e72a79 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_notify_privacy_guard.png diff --git a/core/res/res/drawable-xhdpi/stat_notify_privacy_guard.png b/core/res/res/drawable-xhdpi/stat_notify_privacy_guard.png Binary files differnew file mode 100644 index 0000000..c5e70a2 --- /dev/null +++ b/core/res/res/drawable-xhdpi/stat_notify_privacy_guard.png diff --git a/core/res/res/drawable-xxhdpi/stat_notify_privacy_guard.png b/core/res/res/drawable-xxhdpi/stat_notify_privacy_guard.png Binary files differnew file mode 100644 index 0000000..4f34941 --- /dev/null +++ b/core/res/res/drawable-xxhdpi/stat_notify_privacy_guard.png diff --git a/core/res/res/values/cm_strings.xml b/core/res/res/values/cm_strings.xml index 8b89423..64ea2be 100644 --- a/core/res/res/values/cm_strings.xml +++ b/core/res/res/values/cm_strings.xml @@ -158,4 +158,9 @@ <string name="symbol_picker_lt">\u2264\u00ab\u2039</string> <string name="symbol_picker_gt">\u2265\u00bb\u203a</string> + <!-- Privacy Guard --> + <string name="permlab_changePrivacyGuardState">enable or disable privacy guard</string> + <string name="permdesc_changePrivacyGuardState">Allows the application to change whether another application runs with Privacy Guard. When an application is running with Privacy Guard, it will not have access to personal data such as contacts, call logs, or messages.</string> + <string name="privacy_guard_notification">Privacy Guard active</string> + <string name="privacy_guard_notification_detail"><xliff:g id="app">%1$s</xliff:g> will not be able to access personal data</string> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 0ff9036..3679acb 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2003,4 +2003,8 @@ <!-- Electron Beam --> <java-symbol type="bool" name="config_screenOffAnimation" /> + <!-- Privacy Guard --> + <java-symbol type="string" name="privacy_guard_notification" /> + <java-symbol type="string" name="privacy_guard_notification_detail" /> + <java-symbol type="drawable" name="stat_notify_privacy_guard" /> </resources> |
