From c04860b500bfef92dee099b9384d4f8e5d26d883 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Thu, 14 May 2015 15:17:37 -0700 Subject: Add logging for user permission interactions. bug:21078221 Change-Id: I06dcf4329c1d7eb5924823e633d7a1966a3bd404 --- .../permission/model/Permission.java | 4 ++ .../permission/model/PermissionApps.java | 18 ++++-- .../permission/model/PermissionGroup.java | 10 ++++ .../permission/ui/AppPermissionsFragment.java | 33 ++++++++++ .../permission/ui/GrantPermissionsActivity.java | 20 +++++++ .../permission/ui/PermissionAppsFragment.java | 40 +++++++++++++ .../permission/utils/SafetyNetLogger.java | 70 ++++++++++++++++++++++ 7 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 src/com/android/packageinstaller/permission/utils/SafetyNetLogger.java diff --git a/src/com/android/packageinstaller/permission/model/Permission.java b/src/com/android/packageinstaller/permission/model/Permission.java index 388ae75a..09c927be 100644 --- a/src/com/android/packageinstaller/permission/model/Permission.java +++ b/src/com/android/packageinstaller/permission/model/Permission.java @@ -44,6 +44,10 @@ public final class Permission { return mAppOp; } + public int getFlags() { + return mFlags; + } + public boolean hasAppOp() { return mAppOp != AppOpsManager.OP_NONE; } diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index 81e5af51..d3d46cfa 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -106,12 +106,14 @@ public class PermissionApps { } public static class PermissionApp implements Comparable { + private final String mPackageName; private final PermissionGroup mPermissionGroup; private final String mLabel; private final Drawable mIcon; - public PermissionApp(PermissionGroup permissionGroup, String label, - Drawable icon) { + public PermissionApp(String packageName, PermissionGroup permissionGroup, + String label, Drawable icon) { + mPackageName = packageName; mPermissionGroup = permissionGroup; mLabel = label; mIcon = icon; @@ -149,6 +151,14 @@ public class PermissionApps { return mPermissionGroup.isSystemFixed(); } + public String getPackageName() { + return mPackageName; + } + + public PermissionGroup getPermissionGroup() { + return mPermissionGroup; + } + @Override public int compareTo(PermissionApp another) { final int result = mLabel.compareTo(another.mLabel); @@ -209,8 +219,8 @@ public class PermissionApps { PermissionGroup group = PermissionGroup.create(mContext, app, groupInfo, groupPermInfos); - PermissionApp permApp = new PermissionApp(group, - app.applicationInfo.loadLabel(mPm).toString(), + PermissionApp permApp = new PermissionApp(app.packageName, + group, app.applicationInfo.loadLabel(mPm).toString(), getBadgedIcon(app.applicationInfo)); permApps.add(permApp); diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroup.java b/src/com/android/packageinstaller/permission/model/PermissionGroup.java index 1f20e442..9e90d4ff 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroup.java @@ -402,6 +402,16 @@ public final class PermissionGroup implements Comparable { return new ArrayList<>(mPermissions.values()); } + public int getFlags() { + int flags = 0; + final int permissionCount = mPermissions.size(); + for (int i = 0; i < permissionCount; i++) { + Permission permission = mPermissions.valueAt(i); + flags |= permission.getFlags(); + } + return flags; + } + public boolean isUserFixed() { final int permissionCount = mPermissions.size(); for (int i = 0; i < permissionCount; i++) { diff --git a/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java index 7b64d7b3..a7c404cc 100644 --- a/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/AppPermissionsFragment.java @@ -49,8 +49,12 @@ import android.widget.Toast; import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.PermissionGroup; +import com.android.packageinstaller.permission.utils.SafetyNetLogger; import com.android.packageinstaller.permission.utils.Utils; +import java.util.ArrayList; +import java.util.List; + public final class AppPermissionsFragment extends SettingsWithHeader implements OnPreferenceChangeListener { @@ -60,6 +64,7 @@ public final class AppPermissionsFragment extends SettingsWithHeader private static final String EXTRA_HIDE_INFO_BUTTON = "hideInfoButton"; + private List mToggledGroups; private AppPermissions mAppPermissions; private PreferenceScreen mExtraScreen; @@ -222,6 +227,8 @@ public final class AppPermissionsFragment extends SettingsWithHeader return false; } + addToggledGroup(group); + if (newValue == Boolean.TRUE) { group.grantRuntimePermissions(false); } else { @@ -248,6 +255,32 @@ public final class AppPermissionsFragment extends SettingsWithHeader return true; } + @Override + public void onPause() { + super.onPause(); + logToggledGroups(); + } + + private void addToggledGroup(PermissionGroup group) { + if (mToggledGroups == null) { + mToggledGroups = new ArrayList<>(); + } + // Double toggle is back to initial state. + if (mToggledGroups.contains(group)) { + mToggledGroups.remove(group); + } else { + mToggledGroups.add(group); + } + } + + private void logToggledGroups() { + if (mToggledGroups != null) { + String packageName = mAppPermissions.getPackageInfo().packageName; + SafetyNetLogger.logPermissionsToggled(packageName, mToggledGroups); + mToggledGroups = null; + } + } + private void updateUi() { mAppPermissions.refresh(); diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index 9ed47df9..257a9cc4 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -37,6 +37,10 @@ import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.Permission; import com.android.packageinstaller.permission.model.PermissionGroup; +import com.android.packageinstaller.permission.utils.SafetyNetLogger; + +import java.util.ArrayList; +import java.util.List; public class GrantPermissionsActivity extends Activity implements GrantPermissionViewHandler.OnRequestGrantPermissionGroupResult { @@ -289,6 +293,7 @@ public class GrantPermissionsActivity extends Activity implements } private void setResultAndFinish() { + logRequestedPermissionGroups(); Intent result = new Intent(PackageManager.ACTION_REQUEST_PERMISSIONS); result.putExtra(PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES, mRequestedPermissions); result.putExtra(PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS, mGrantResults); @@ -296,6 +301,21 @@ public class GrantPermissionsActivity extends Activity implements finish(); } + private void logRequestedPermissionGroups() { + if (mRequestGrantPermissionGroups.isEmpty()) { + return; + } + + final int groupCount = mRequestGrantPermissionGroups.size(); + List groups = new ArrayList<>(groupCount); + for (int i = 0; i < groupCount; i++) { + groups.add(mRequestGrantPermissionGroups.valueAt(i).mGroup); + } + + SafetyNetLogger.logPermissionsRequested(mAppPermissions.getPackageInfo() + .packageName, groups); + } + private static final class GroupState { public static final int STATE_UNKNOWN = 0; public static final int STATE_ALLOWED = 1; diff --git a/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java index f18acfe3..dae90b93 100644 --- a/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/PermissionAppsFragment.java @@ -25,6 +25,7 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceScreen; import android.preference.SwitchPreference; +import android.support.v4.util.ArrayMap; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; @@ -36,6 +37,11 @@ import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.Callback; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; +import com.android.packageinstaller.permission.model.PermissionGroup; +import com.android.packageinstaller.permission.utils.SafetyNetLogger; + +import java.util.ArrayList; +import java.util.List; public final class PermissionAppsFragment extends SettingsWithHeader implements Callback, OnPreferenceChangeListener { @@ -50,6 +56,8 @@ public final class PermissionAppsFragment extends SettingsWithHeader implements private PermissionApps mPermissionApps; + private ArrayMap mToggledGroups; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -156,6 +164,8 @@ public final class PermissionAppsFragment extends SettingsWithHeader implements String pkg = preference.getKey(); PermissionApp app = mPermissionApps.getApp(pkg); + addToggledGroup(app.getPackageName(), app.getPermissionGroup()); + if (app == null) { return false; } @@ -167,4 +177,34 @@ public final class PermissionAppsFragment extends SettingsWithHeader implements return true; } + @Override + public void onPause() { + super.onPause(); + logToggledGroups(); + } + + private void addToggledGroup(String packageName, PermissionGroup group) { + if (mToggledGroups == null) { + mToggledGroups = new ArrayMap<>(); + } + // Double toggle is back to initial state. + if (mToggledGroups.containsKey(packageName)) { + mToggledGroups.remove(packageName); + } else { + mToggledGroups.put(packageName, group); + } + } + + private void logToggledGroups() { + if (mToggledGroups != null) { + final int groupCount = mToggledGroups.size(); + for (int i = 0; i < groupCount; i++) { + String packageName = mToggledGroups.keyAt(i); + List groups = new ArrayList<>(); + groups.add(mToggledGroups.valueAt(i)); + SafetyNetLogger.logPermissionsToggled(packageName, groups); + } + mToggledGroups = null; + } + } } diff --git a/src/com/android/packageinstaller/permission/utils/SafetyNetLogger.java b/src/com/android/packageinstaller/permission/utils/SafetyNetLogger.java new file mode 100644 index 00000000..b1e27286 --- /dev/null +++ b/src/com/android/packageinstaller/permission/utils/SafetyNetLogger.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015 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.packageinstaller.permission.utils; + +import android.util.EventLog; +import com.android.packageinstaller.permission.model.PermissionGroup; + +import java.util.List; + +public final class SafetyNetLogger { + + // The log tag used by SafetyNet to pick entries from the event log. + private static final int SNET_NET_EVENT_LOG_TAG = 0x534e4554; + + // Log tag for the result of permissions request. + private static final String PERMISSIONS_REQUESTED = "permissions_requested"; + + // Log tag for the result of permissions toggling. + private static final String PERMISSIONS_TOGGLED = "permissions_toggled"; + + private SafetyNetLogger() { + /* do nothing */ + } + + public static void logPermissionsRequested(String packageName, List groups) { + EventLog.writeEvent(SNET_NET_EVENT_LOG_TAG, PERMISSIONS_REQUESTED, + android.os.Process.myUid(), buildChangedGroupForPackageMessage( + packageName, groups)); + } + + public static void logPermissionsToggled(String packageName, List groups) { + EventLog.writeEvent(SNET_NET_EVENT_LOG_TAG, PERMISSIONS_TOGGLED, + android.os.Process.myUid(), buildChangedGroupForPackageMessage( + packageName, groups)); + } + + private static String buildChangedGroupForPackageMessage(String packageName, + List groups) { + StringBuilder builder = new StringBuilder(); + + builder.append(packageName).append(':'); + + final int groupCount = groups.size(); + for (int i = 0; i < groupCount; i++) { + PermissionGroup group = groups.get(i); + if (i > 0) { + builder.append(';'); + } + builder.append(group.getName()).append('|'); + builder.append(group.areRuntimePermissionsGranted()).append('|'); + builder.append(group.getFlags()); + } + + return builder.toString(); + } +} -- cgit v1.2.3