OSDN Git Service

Merge cherrypicks of [2973982, 2974657, 2974658, 2973983, 2973984, 2974689, 2974690...
authorandroid-build-team Robot <android-build-team-robot@google.com>
Thu, 28 Sep 2017 17:16:10 +0000 (17:16 +0000)
committerandroid-build-team Robot <android-build-team-robot@google.com>
Thu, 28 Sep 2017 17:16:10 +0000 (17:16 +0000)
Change-Id: Iba445710659313fab4ac001284a3b5eff3566540

core/java/android/service/gatekeeper/GateKeeperResponse.java
packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
services/core/java/com/android/server/clipboard/ClipboardService.java
services/core/java/com/android/server/content/SyncStorageEngine.java
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java

index a512957..6ca6d8a 100644 (file)
@@ -85,6 +85,8 @@ public final class GateKeeperResponse implements Parcelable {
             if (mPayload != null) {
                 dest.writeInt(mPayload.length);
                 dest.writeByteArray(mPayload);
+            } else {
+                dest.writeInt(0);
             }
         }
     }
index 9d22b4a..7639b3d 100644 (file)
@@ -2679,4 +2679,23 @@ public abstract class BaseStatusBar extends SystemUI implements
             mAssistManager.startAssist(args);
         }
     }
+
+    public boolean isCameraAllowedByAdmin() {
+       if (mDevicePolicyManager.getCameraDisabled(null, mCurrentUserId)) {
+           return false;
+       } else if (isKeyguardShowing() && isKeyguardSecure()) {
+           // Check if the admin has disabled the camera specifically for the keyguard
+           return (mDevicePolicyManager.getKeyguardDisabledFeatures(null, mCurrentUserId)
+                   & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
+       }
+       return true;
+    }
+
+    public boolean isKeyguardShowing() {
+        if (mStatusBarKeyguardViewManager == null) {
+            Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true");
+            return true;
+        }
+        return mStatusBarKeyguardViewManager.isShowing();
+    }
 }
index 4d0e5d3..c674a82 100644 (file)
@@ -305,7 +305,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
             return;
         }
         ResolveInfo resolved = resolveCameraIntent();
-        boolean visible = !isCameraDisabledByDpm() && resolved != null
+        boolean isCameraDisabled =
+                (mPhoneStatusBar != null) && !mPhoneStatusBar.isCameraAllowedByAdmin();
+        boolean visible = !isCameraDisabled
+                && resolved != null
                 && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
                 && mUserSetupComplete;
         mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
@@ -339,24 +342,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
                 && pm.resolveActivity(PHONE_INTENT, 0) != null;
     }
 
-    private boolean isCameraDisabledByDpm() {
-        final DevicePolicyManager dpm =
-                (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
-        if (dpm != null && mPhoneStatusBar != null) {
-            try {
-                final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
-                final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
-                final  boolean disabledBecauseKeyguardSecure =
-                        (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
-                                && mPhoneStatusBar.isKeyguardSecure();
-                return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
-            } catch (RemoteException e) {
-                Log.e(TAG, "Can't get userId", e);
-            }
-        }
-        return false;
-    }
-
     private void watchForCameraPolicyChanges() {
         final IntentFilter filter = new IntentFilter();
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
index 9c700b4..ca08ab1 100644 (file)
@@ -31,6 +31,7 @@ import android.graphics.Paint;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.MathUtils;
+import android.util.EventLog;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -2330,6 +2331,10 @@ public class NotificationPanelView extends PanelView implements
      * @param keyguardIsShowing whether keyguard is being shown
      */
     public boolean canCameraGestureBeLaunched(boolean keyguardIsShowing) {
+        if (!mStatusBar.isCameraAllowedByAdmin()) {
+            EventLog.writeEvent(0x534e4554, "63787722", -1, "");
+            return false;
+        }
         ResolveInfo resolveInfo = mKeyguardBottomArea.resolveCameraIntent();
         String packageToLaunch = (resolveInfo == null || resolveInfo.activityInfo == null)
                 ? null : resolveInfo.activityInfo.packageName;
index 66aa403..bdd2d2b 100644 (file)
@@ -20,6 +20,7 @@ import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
+import android.app.KeyguardManager;
 import android.content.BroadcastReceiver;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -255,7 +256,7 @@ public class ClipboardService extends IClipboard.Stub {
     public ClipData getPrimaryClip(String pkg) {
         synchronized (this) {
             if (mAppOps.noteOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(),
-                    pkg) != AppOpsManager.MODE_ALLOWED) {
+                    pkg) != AppOpsManager.MODE_ALLOWED || isDeviceLocked()) {
                 return null;
             }
             addActiveOwnerLocked(Binder.getCallingUid(), pkg);
@@ -266,7 +267,7 @@ public class ClipboardService extends IClipboard.Stub {
     public ClipDescription getPrimaryClipDescription(String callingPackage) {
         synchronized (this) {
             if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(),
-                    callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                    callingPackage) != AppOpsManager.MODE_ALLOWED || isDeviceLocked()) {
                 return null;
             }
             PerUserClipboard clipboard = getClipboard();
@@ -277,7 +278,7 @@ public class ClipboardService extends IClipboard.Stub {
     public boolean hasPrimaryClip(String callingPackage) {
         synchronized (this) {
             if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(),
-                    callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                    callingPackage) != AppOpsManager.MODE_ALLOWED || isDeviceLocked()) {
                 return false;
             }
             return getClipboard().primaryClip != null;
@@ -301,7 +302,7 @@ public class ClipboardService extends IClipboard.Stub {
     public boolean hasClipboardText(String callingPackage) {
         synchronized (this) {
             if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(),
-                    callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                    callingPackage) != AppOpsManager.MODE_ALLOWED || isDeviceLocked()) {
                 return false;
             }
             PerUserClipboard clipboard = getClipboard();
@@ -313,6 +314,11 @@ public class ClipboardService extends IClipboard.Stub {
         }
     }
 
+    private boolean isDeviceLocked() {
+        final KeyguardManager keyguardManager = mContext.getSystemService(KeyguardManager.class);
+        return keyguardManager != null && keyguardManager.isDeviceLocked();
+    }
+
     private final void checkUriOwnerLocked(Uri uri, int uid) {
         if (!"content".equals(uri.getScheme())) {
             return;
index 069ae73..f804fa1 100644 (file)
@@ -18,6 +18,7 @@ package com.android.server.content;
 
 import android.accounts.Account;
 import android.accounts.AccountAndUser;
+import android.accounts.AccountManager;
 import android.app.backup.BackupManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -27,6 +28,7 @@ import android.content.PeriodicSync;
 import android.content.SyncInfo;
 import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
@@ -350,6 +352,50 @@ public class SyncStorageEngine extends Handler {
         void onAuthorityRemoved(EndPoint removedAuthority);
     }
 
+    /**
+     * Validator that maintains a lazy cache of accounts and providers to tell if an authority or
+     * account is valid.
+     */
+    private static class AccountAuthorityValidator {
+        final private AccountManager mAccountManager;
+        final private PackageManager mPackageManager;
+        final private SparseArray<Account[]> mAccountsCache;
+        final private SparseArray<ArrayMap<String, Boolean>> mProvidersPerUserCache;
+
+        AccountAuthorityValidator(Context context) {
+            mAccountManager = context.getSystemService(AccountManager.class);
+            mPackageManager = context.getPackageManager();
+            mAccountsCache = new SparseArray<>();
+            mProvidersPerUserCache = new SparseArray<>();
+        }
+
+        // An account is valid if an installed authenticator has previously created that account
+        // on the device
+        boolean isAccountValid(Account account, int userId) {
+            Account[] accountsForUser = mAccountsCache.get(userId);
+            if (accountsForUser == null) {
+                accountsForUser = mAccountManager.getAccountsAsUser(userId);
+                mAccountsCache.put(userId, accountsForUser);
+            }
+            return ArrayUtils.contains(accountsForUser, account);
+        }
+
+        // An authority is only valid if it has a content provider installed on the system
+        boolean isAuthorityValid(String authority, int userId) {
+            ArrayMap<String, Boolean> authorityMap = mProvidersPerUserCache.get(userId);
+            if (authorityMap == null) {
+                authorityMap = new ArrayMap<>();
+                mProvidersPerUserCache.put(userId, authorityMap);
+            }
+            if (!authorityMap.containsKey(authority)) {
+                authorityMap.put(authority, mPackageManager.resolveContentProviderAsUser(authority,
+                        PackageManager.MATCH_DIRECT_BOOT_AWARE
+                                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId) != null);
+            }
+            return authorityMap.get(authority);
+        }
+    }
+
     // Primary list of all syncable authorities.  Also our global lock.
     private final SparseArray<AuthorityInfo> mAuthorities =
             new SparseArray<AuthorityInfo>();
@@ -1502,12 +1548,13 @@ public class SyncStorageEngine extends Handler {
                 eventType = parser.next();
                 AuthorityInfo authority = null;
                 PeriodicSync periodicSync = null;
+                AccountAuthorityValidator validator = new AccountAuthorityValidator(mContext);
                 do {
                     if (eventType == XmlPullParser.START_TAG) {
                         tagName = parser.getName();
                         if (parser.getDepth() == 2) {
                             if ("authority".equals(tagName)) {
-                                authority = parseAuthority(parser, version);
+                                authority = parseAuthority(parser, version, validator);
                                 periodicSync = null;
                                 if (authority != null) {
                                     if (authority.ident > highestAuthorityId) {
@@ -1636,7 +1683,8 @@ public class SyncStorageEngine extends Handler {
         mMasterSyncAutomatically.put(userId, listen);
     }
 
-    private AuthorityInfo parseAuthority(XmlPullParser parser, int version) {
+    private AuthorityInfo parseAuthority(XmlPullParser parser, int version,
+            AccountAuthorityValidator validator) {
         AuthorityInfo authority = null;
         int id = -1;
         try {
@@ -1676,21 +1724,26 @@ public class SyncStorageEngine extends Handler {
                 if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
                     Slog.v(TAG_FILE, "Creating authority entry");
                 }
-                EndPoint info = null;
                 if (accountName != null && authorityName != null) {
-                    info = new EndPoint(
+                    EndPoint info = new EndPoint(
                             new Account(accountName, accountType),
                             authorityName, userId);
-                }
-                if (info != null) {
-                    authority = getOrCreateAuthorityLocked(info, id, false);
-                    // If the version is 0 then we are upgrading from a file format that did not
-                    // know about periodic syncs. In that case don't clear the list since we
-                    // want the default, which is a daily periodic sync.
-                    // Otherwise clear out this default list since we will populate it later with
-                    // the periodic sync descriptions that are read from the configuration file.
-                    if (version > 0) {
-                        authority.periodicSyncs.clear();
+                    if (validator.isAccountValid(info.account, userId)
+                            && validator.isAuthorityValid(authorityName, userId)) {
+                        authority = getOrCreateAuthorityLocked(info, id, false);
+                        // If the version is 0 then we are upgrading from a file format that did not
+                        // know about periodic syncs. In that case don't clear the list since we
+                        // want the default, which is a daily periodic sync.
+                        // Otherwise clear out this default list since we will populate it later
+                        // with
+                        // the periodic sync descriptions that are read from the configuration file.
+                        if (version > 0) {
+                            authority.periodicSyncs.clear();
+                        }
+                    } else {
+                        EventLog.writeEvent(0x534e4554, "35028827", -1,
+                                "account:" + info.account + " provider:" + authorityName + " user:"
+                                        + userId);
                     }
                 }
             }
index e3b6ecc..f3b3c67 100644 (file)
@@ -71,6 +71,7 @@ import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ParceledListSlice;
+import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.UserInfo;
@@ -123,6 +124,7 @@ import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.EventLog;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
@@ -8621,6 +8623,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                         < android.os.Build.VERSION_CODES.M) {
                     return false;
                 }
+                if (!isRuntimePermission(permission)) {
+                    EventLog.writeEvent(0x534e4554, "62623498", user.getIdentifier(), "");
+                    return false;
+                }
                 final PackageManager packageManager = mContext.getPackageManager();
                 switch (grantState) {
                     case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: {
@@ -8646,12 +8652,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                 return true;
             } catch (SecurityException se) {
                 return false;
+            } catch (NameNotFoundException e) {
+                return false;
             } finally {
                 mInjector.binderRestoreCallingIdentity(ident);
             }
         }
     }
 
+    public boolean isRuntimePermission(String permissionName) throws NameNotFoundException {
+        final PackageManager packageManager = mContext.getPackageManager();
+        PermissionInfo permissionInfo = packageManager.getPermissionInfo(permissionName, 0);
+        return (permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+                == PermissionInfo.PROTECTION_DANGEROUS;
+    }
+
     @Override
     public int getPermissionGrantState(ComponentName admin, String packageName,
             String permission) throws RemoteException {