frameworks/base
Revision | 9abeb4e2a077d014b4766ff04c557a1e57b013d2 (tree) |
---|---|
Time | 2018-01-04 17:31:43 |
Author | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge tag 'android-7.1.2_r36' into nougat-x86
Android 7.1.2 Release 36 (N2G48H)
@@ -112,6 +112,7 @@ package android { | ||
112 | 112 | field public static final java.lang.String GRANT_RUNTIME_PERMISSIONS = "android.permission.GRANT_RUNTIME_PERMISSIONS"; |
113 | 113 | field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST"; |
114 | 114 | field public static final java.lang.String HDMI_CEC = "android.permission.HDMI_CEC"; |
115 | + field public static final java.lang.String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"; | |
115 | 116 | field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS"; |
116 | 117 | field public static final java.lang.String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"; |
117 | 118 | field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER"; |
@@ -85,6 +85,8 @@ public final class GateKeeperResponse implements Parcelable { | ||
85 | 85 | if (mPayload != null) { |
86 | 86 | dest.writeInt(mPayload.length); |
87 | 87 | dest.writeByteArray(mPayload); |
88 | + } else { | |
89 | + dest.writeInt(0); | |
88 | 90 | } |
89 | 91 | } |
90 | 92 | } |
@@ -655,6 +655,25 @@ public interface WindowManager extends ViewManager { | ||
655 | 655 | */ |
656 | 656 | public static final int LAST_SYSTEM_WINDOW = 2999; |
657 | 657 | |
658 | + /** | |
659 | + * Return true if the window type is an alert window. | |
660 | + * | |
661 | + * @param type The window type. | |
662 | + * @return If the window type is an alert window. | |
663 | + * @hide | |
664 | + */ | |
665 | + public static boolean isSystemAlertWindowType(int type) { | |
666 | + switch (type) { | |
667 | + case TYPE_PHONE: | |
668 | + case TYPE_PRIORITY_PHONE: | |
669 | + case TYPE_SYSTEM_ALERT: | |
670 | + case TYPE_SYSTEM_ERROR: | |
671 | + case TYPE_SYSTEM_OVERLAY: | |
672 | + return true; | |
673 | + } | |
674 | + return false; | |
675 | + } | |
676 | + | |
658 | 677 | /** @deprecated this is ignored, this value is set automatically when needed. */ |
659 | 678 | @Deprecated |
660 | 679 | public static final int MEMORY_TYPE_NORMAL = 0; |
@@ -1263,6 +1282,15 @@ public interface WindowManager extends ViewManager { | ||
1263 | 1282 | public static final int PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE = 0x00040000; |
1264 | 1283 | |
1265 | 1284 | /** |
1285 | + * Flag to indicate that any window added by an application process that is of type | |
1286 | + * {@link #TYPE_TOAST} or that requires | |
1287 | + * {@link android.app.AppOpsManager#OP_SYSTEM_ALERT_WINDOW} permission should be hidden when | |
1288 | + * this window is visible. | |
1289 | + * @hide | |
1290 | + */ | |
1291 | + public static final int PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 0x00080000; | |
1292 | + | |
1293 | + /** | |
1266 | 1294 | * Control flags that are private to the platform. |
1267 | 1295 | * @hide |
1268 | 1296 | */ |
@@ -587,8 +587,7 @@ static jobject nativeDecodeFileDescriptor(JNIEnv* env, jobject clazz, jobject fi | ||
587 | 587 | return nullObjectReturn("Could not open file"); |
588 | 588 | } |
589 | 589 | |
590 | - std::unique_ptr<SkFILEStream> fileStream(new SkFILEStream(file, | |
591 | - SkFILEStream::kCallerPasses_Ownership)); | |
590 | + std::unique_ptr<SkFILEStream> fileStream(new SkFILEStream(file)); | |
592 | 591 | |
593 | 592 | // If there is no offset for the file descriptor, we use SkFILEStream directly. |
594 | 593 | if (::lseek(descriptor, 0, SEEK_CUR) == 0) { |
@@ -2154,6 +2154,15 @@ | ||
2154 | 2154 | <permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" |
2155 | 2155 | android:protectionLevel="signature" /> |
2156 | 2156 | |
2157 | + <!-- @SystemApi Allows an application to use | |
2158 | + {@link android.view.WindowManager.LayoutsParams#PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS} | |
2159 | + to hide non-system-overlay windows. | |
2160 | + <p>Not for use by third-party applications. | |
2161 | + @hide | |
2162 | + --> | |
2163 | + <permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" | |
2164 | + android:protectionLevel="signature|installer" /> | |
2165 | + | |
2157 | 2166 | <!-- @SystemApi Allows an application to manage (create, destroy, |
2158 | 2167 | Z-order) application tokens in the window manager. |
2159 | 2168 | <p>Not for use by third-party applications. |
@@ -390,8 +390,7 @@ static jobject ExifInterface_getRawAttributesFromFileDescriptor( | ||
390 | 390 | // Rewind the file descriptor. |
391 | 391 | fseek(file, 0L, SEEK_SET); |
392 | 392 | |
393 | - std::unique_ptr<SkFILEStream> fileStream(new SkFILEStream(file, | |
394 | - SkFILEStream::kCallerPasses_Ownership)); | |
393 | + std::unique_ptr<SkFILEStream> fileStream(new SkFILEStream(file)); | |
395 | 394 | return getRawAttributes(env, fileStream.get(), false); |
396 | 395 | } |
397 | 396 |
@@ -2679,4 +2679,23 @@ public abstract class BaseStatusBar extends SystemUI implements | ||
2679 | 2679 | mAssistManager.startAssist(args); |
2680 | 2680 | } |
2681 | 2681 | } |
2682 | + | |
2683 | + public boolean isCameraAllowedByAdmin() { | |
2684 | + if (mDevicePolicyManager.getCameraDisabled(null, mCurrentUserId)) { | |
2685 | + return false; | |
2686 | + } else if (isKeyguardShowing() && isKeyguardSecure()) { | |
2687 | + // Check if the admin has disabled the camera specifically for the keyguard | |
2688 | + return (mDevicePolicyManager.getKeyguardDisabledFeatures(null, mCurrentUserId) | |
2689 | + & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0; | |
2690 | + } | |
2691 | + return true; | |
2692 | + } | |
2693 | + | |
2694 | + public boolean isKeyguardShowing() { | |
2695 | + if (mStatusBarKeyguardViewManager == null) { | |
2696 | + Slog.i(TAG, "isKeyguardShowing() called before startKeyguard(), returning true"); | |
2697 | + return true; | |
2698 | + } | |
2699 | + return mStatusBarKeyguardViewManager.isShowing(); | |
2700 | + } | |
2682 | 2701 | } |
@@ -305,7 +305,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL | ||
305 | 305 | return; |
306 | 306 | } |
307 | 307 | ResolveInfo resolved = resolveCameraIntent(); |
308 | - boolean visible = !isCameraDisabledByDpm() && resolved != null | |
308 | + boolean isCameraDisabled = | |
309 | + (mPhoneStatusBar != null) && !mPhoneStatusBar.isCameraAllowedByAdmin(); | |
310 | + boolean visible = !isCameraDisabled | |
311 | + && resolved != null | |
309 | 312 | && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance) |
310 | 313 | && mUserSetupComplete; |
311 | 314 | mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE); |
@@ -339,24 +342,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL | ||
339 | 342 | && pm.resolveActivity(PHONE_INTENT, 0) != null; |
340 | 343 | } |
341 | 344 | |
342 | - private boolean isCameraDisabledByDpm() { | |
343 | - final DevicePolicyManager dpm = | |
344 | - (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE); | |
345 | - if (dpm != null && mPhoneStatusBar != null) { | |
346 | - try { | |
347 | - final int userId = ActivityManagerNative.getDefault().getCurrentUser().id; | |
348 | - final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId); | |
349 | - final boolean disabledBecauseKeyguardSecure = | |
350 | - (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0 | |
351 | - && mPhoneStatusBar.isKeyguardSecure(); | |
352 | - return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure; | |
353 | - } catch (RemoteException e) { | |
354 | - Log.e(TAG, "Can't get userId", e); | |
355 | - } | |
356 | - } | |
357 | - return false; | |
358 | - } | |
359 | - | |
360 | 345 | private void watchForCameraPolicyChanges() { |
361 | 346 | final IntentFilter filter = new IntentFilter(); |
362 | 347 | filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); |
@@ -31,6 +31,7 @@ import android.graphics.Paint; | ||
31 | 31 | import android.graphics.Rect; |
32 | 32 | import android.util.AttributeSet; |
33 | 33 | import android.util.MathUtils; |
34 | +import android.util.EventLog; | |
34 | 35 | import android.view.MotionEvent; |
35 | 36 | import android.view.VelocityTracker; |
36 | 37 | import android.view.View; |
@@ -2330,6 +2331,10 @@ public class NotificationPanelView extends PanelView implements | ||
2330 | 2331 | * @param keyguardIsShowing whether keyguard is being shown |
2331 | 2332 | */ |
2332 | 2333 | public boolean canCameraGestureBeLaunched(boolean keyguardIsShowing) { |
2334 | + if (!mStatusBar.isCameraAllowedByAdmin()) { | |
2335 | + EventLog.writeEvent(0x534e4554, "63787722", -1, ""); | |
2336 | + return false; | |
2337 | + } | |
2333 | 2338 | ResolveInfo resolveInfo = mKeyguardBottomArea.resolveCameraIntent(); |
2334 | 2339 | String packageToLaunch = (resolveInfo == null || resolveInfo.activityInfo == null) |
2335 | 2340 | ? null : resolveInfo.activityInfo.packageName; |
@@ -4184,6 +4184,10 @@ public class AccountManagerService | ||
4184 | 4184 | protected void checkKeyIntent( |
4185 | 4185 | int authUid, |
4186 | 4186 | Intent intent) throws SecurityException { |
4187 | + intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION | |
4188 | + | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | |
4189 | + | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | |
4190 | + | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)); | |
4187 | 4191 | long bid = Binder.clearCallingIdentity(); |
4188 | 4192 | try { |
4189 | 4193 | PackageManager pm = mContext.getPackageManager(); |
@@ -20,6 +20,7 @@ import android.app.ActivityManagerNative; | ||
20 | 20 | import android.app.AppGlobals; |
21 | 21 | import android.app.AppOpsManager; |
22 | 22 | import android.app.IActivityManager; |
23 | +import android.app.KeyguardManager; | |
23 | 24 | import android.content.BroadcastReceiver; |
24 | 25 | import android.content.ClipData; |
25 | 26 | import android.content.ClipDescription; |
@@ -255,7 +256,7 @@ public class ClipboardService extends IClipboard.Stub { | ||
255 | 256 | public ClipData getPrimaryClip(String pkg) { |
256 | 257 | synchronized (this) { |
257 | 258 | if (mAppOps.noteOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), |
258 | - pkg) != AppOpsManager.MODE_ALLOWED) { | |
259 | + pkg) != AppOpsManager.MODE_ALLOWED || isDeviceLocked()) { | |
259 | 260 | return null; |
260 | 261 | } |
261 | 262 | addActiveOwnerLocked(Binder.getCallingUid(), pkg); |
@@ -266,7 +267,7 @@ public class ClipboardService extends IClipboard.Stub { | ||
266 | 267 | public ClipDescription getPrimaryClipDescription(String callingPackage) { |
267 | 268 | synchronized (this) { |
268 | 269 | if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), |
269 | - callingPackage) != AppOpsManager.MODE_ALLOWED) { | |
270 | + callingPackage) != AppOpsManager.MODE_ALLOWED || isDeviceLocked()) { | |
270 | 271 | return null; |
271 | 272 | } |
272 | 273 | PerUserClipboard clipboard = getClipboard(); |
@@ -277,7 +278,7 @@ public class ClipboardService extends IClipboard.Stub { | ||
277 | 278 | public boolean hasPrimaryClip(String callingPackage) { |
278 | 279 | synchronized (this) { |
279 | 280 | if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), |
280 | - callingPackage) != AppOpsManager.MODE_ALLOWED) { | |
281 | + callingPackage) != AppOpsManager.MODE_ALLOWED || isDeviceLocked()) { | |
281 | 282 | return false; |
282 | 283 | } |
283 | 284 | return getClipboard().primaryClip != null; |
@@ -301,7 +302,7 @@ public class ClipboardService extends IClipboard.Stub { | ||
301 | 302 | public boolean hasClipboardText(String callingPackage) { |
302 | 303 | synchronized (this) { |
303 | 304 | if (mAppOps.checkOp(AppOpsManager.OP_READ_CLIPBOARD, Binder.getCallingUid(), |
304 | - callingPackage) != AppOpsManager.MODE_ALLOWED) { | |
305 | + callingPackage) != AppOpsManager.MODE_ALLOWED || isDeviceLocked()) { | |
305 | 306 | return false; |
306 | 307 | } |
307 | 308 | PerUserClipboard clipboard = getClipboard(); |
@@ -313,6 +314,17 @@ public class ClipboardService extends IClipboard.Stub { | ||
313 | 314 | } |
314 | 315 | } |
315 | 316 | |
317 | + private boolean isDeviceLocked() { | |
318 | + final long token = Binder.clearCallingIdentity(); | |
319 | + try { | |
320 | + final KeyguardManager keyguardManager = mContext.getSystemService( | |
321 | + KeyguardManager.class); | |
322 | + return keyguardManager != null && keyguardManager.isDeviceLocked(); | |
323 | + } finally { | |
324 | + Binder.restoreCallingIdentity(token); | |
325 | + } | |
326 | + } | |
327 | + | |
316 | 328 | private final void checkUriOwnerLocked(Uri uri, int uid) { |
317 | 329 | if (!"content".equals(uri.getScheme())) { |
318 | 330 | return; |
@@ -18,6 +18,7 @@ package com.android.server.content; | ||
18 | 18 | |
19 | 19 | import android.accounts.Account; |
20 | 20 | import android.accounts.AccountAndUser; |
21 | +import android.accounts.AccountManager; | |
21 | 22 | import android.app.backup.BackupManager; |
22 | 23 | import android.content.ComponentName; |
23 | 24 | import android.content.ContentResolver; |
@@ -27,6 +28,7 @@ import android.content.PeriodicSync; | ||
27 | 28 | import android.content.SyncInfo; |
28 | 29 | import android.content.SyncRequest; |
29 | 30 | import android.content.SyncStatusInfo; |
31 | +import android.content.pm.PackageManager; | |
30 | 32 | import android.database.Cursor; |
31 | 33 | import android.database.sqlite.SQLiteDatabase; |
32 | 34 | import android.database.sqlite.SQLiteException; |
@@ -350,6 +352,50 @@ public class SyncStorageEngine extends Handler { | ||
350 | 352 | void onAuthorityRemoved(EndPoint removedAuthority); |
351 | 353 | } |
352 | 354 | |
355 | + /** | |
356 | + * Validator that maintains a lazy cache of accounts and providers to tell if an authority or | |
357 | + * account is valid. | |
358 | + */ | |
359 | + private static class AccountAuthorityValidator { | |
360 | + final private AccountManager mAccountManager; | |
361 | + final private PackageManager mPackageManager; | |
362 | + final private SparseArray<Account[]> mAccountsCache; | |
363 | + final private SparseArray<ArrayMap<String, Boolean>> mProvidersPerUserCache; | |
364 | + | |
365 | + AccountAuthorityValidator(Context context) { | |
366 | + mAccountManager = context.getSystemService(AccountManager.class); | |
367 | + mPackageManager = context.getPackageManager(); | |
368 | + mAccountsCache = new SparseArray<>(); | |
369 | + mProvidersPerUserCache = new SparseArray<>(); | |
370 | + } | |
371 | + | |
372 | + // An account is valid if an installed authenticator has previously created that account | |
373 | + // on the device | |
374 | + boolean isAccountValid(Account account, int userId) { | |
375 | + Account[] accountsForUser = mAccountsCache.get(userId); | |
376 | + if (accountsForUser == null) { | |
377 | + accountsForUser = mAccountManager.getAccountsAsUser(userId); | |
378 | + mAccountsCache.put(userId, accountsForUser); | |
379 | + } | |
380 | + return ArrayUtils.contains(accountsForUser, account); | |
381 | + } | |
382 | + | |
383 | + // An authority is only valid if it has a content provider installed on the system | |
384 | + boolean isAuthorityValid(String authority, int userId) { | |
385 | + ArrayMap<String, Boolean> authorityMap = mProvidersPerUserCache.get(userId); | |
386 | + if (authorityMap == null) { | |
387 | + authorityMap = new ArrayMap<>(); | |
388 | + mProvidersPerUserCache.put(userId, authorityMap); | |
389 | + } | |
390 | + if (!authorityMap.containsKey(authority)) { | |
391 | + authorityMap.put(authority, mPackageManager.resolveContentProviderAsUser(authority, | |
392 | + PackageManager.MATCH_DIRECT_BOOT_AWARE | |
393 | + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId) != null); | |
394 | + } | |
395 | + return authorityMap.get(authority); | |
396 | + } | |
397 | + } | |
398 | + | |
353 | 399 | // Primary list of all syncable authorities. Also our global lock. |
354 | 400 | private final SparseArray<AuthorityInfo> mAuthorities = |
355 | 401 | new SparseArray<AuthorityInfo>(); |
@@ -1502,12 +1548,13 @@ public class SyncStorageEngine extends Handler { | ||
1502 | 1548 | eventType = parser.next(); |
1503 | 1549 | AuthorityInfo authority = null; |
1504 | 1550 | PeriodicSync periodicSync = null; |
1551 | + AccountAuthorityValidator validator = new AccountAuthorityValidator(mContext); | |
1505 | 1552 | do { |
1506 | 1553 | if (eventType == XmlPullParser.START_TAG) { |
1507 | 1554 | tagName = parser.getName(); |
1508 | 1555 | if (parser.getDepth() == 2) { |
1509 | 1556 | if ("authority".equals(tagName)) { |
1510 | - authority = parseAuthority(parser, version); | |
1557 | + authority = parseAuthority(parser, version, validator); | |
1511 | 1558 | periodicSync = null; |
1512 | 1559 | if (authority != null) { |
1513 | 1560 | if (authority.ident > highestAuthorityId) { |
@@ -1636,7 +1683,8 @@ public class SyncStorageEngine extends Handler { | ||
1636 | 1683 | mMasterSyncAutomatically.put(userId, listen); |
1637 | 1684 | } |
1638 | 1685 | |
1639 | - private AuthorityInfo parseAuthority(XmlPullParser parser, int version) { | |
1686 | + private AuthorityInfo parseAuthority(XmlPullParser parser, int version, | |
1687 | + AccountAuthorityValidator validator) { | |
1640 | 1688 | AuthorityInfo authority = null; |
1641 | 1689 | int id = -1; |
1642 | 1690 | try { |
@@ -1676,21 +1724,26 @@ public class SyncStorageEngine extends Handler { | ||
1676 | 1724 | if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) { |
1677 | 1725 | Slog.v(TAG_FILE, "Creating authority entry"); |
1678 | 1726 | } |
1679 | - EndPoint info = null; | |
1680 | 1727 | if (accountName != null && authorityName != null) { |
1681 | - info = new EndPoint( | |
1728 | + EndPoint info = new EndPoint( | |
1682 | 1729 | new Account(accountName, accountType), |
1683 | 1730 | authorityName, userId); |
1684 | - } | |
1685 | - if (info != null) { | |
1686 | - authority = getOrCreateAuthorityLocked(info, id, false); | |
1687 | - // If the version is 0 then we are upgrading from a file format that did not | |
1688 | - // know about periodic syncs. In that case don't clear the list since we | |
1689 | - // want the default, which is a daily periodic sync. | |
1690 | - // Otherwise clear out this default list since we will populate it later with | |
1691 | - // the periodic sync descriptions that are read from the configuration file. | |
1692 | - if (version > 0) { | |
1693 | - authority.periodicSyncs.clear(); | |
1731 | + if (validator.isAccountValid(info.account, userId) | |
1732 | + && validator.isAuthorityValid(authorityName, userId)) { | |
1733 | + authority = getOrCreateAuthorityLocked(info, id, false); | |
1734 | + // If the version is 0 then we are upgrading from a file format that did not | |
1735 | + // know about periodic syncs. In that case don't clear the list since we | |
1736 | + // want the default, which is a daily periodic sync. | |
1737 | + // Otherwise clear out this default list since we will populate it later | |
1738 | + // with | |
1739 | + // the periodic sync descriptions that are read from the configuration file. | |
1740 | + if (version > 0) { | |
1741 | + authority.periodicSyncs.clear(); | |
1742 | + } | |
1743 | + } else { | |
1744 | + EventLog.writeEvent(0x534e4554, "35028827", -1, | |
1745 | + "account:" + info.account + " provider:" + authorityName + " user:" | |
1746 | + + userId); | |
1694 | 1747 | } |
1695 | 1748 | } |
1696 | 1749 | } |
@@ -16,6 +16,9 @@ | ||
16 | 16 | |
17 | 17 | package com.android.server.wm; |
18 | 18 | |
19 | +import static android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS; | |
20 | +import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; | |
21 | +import static android.content.pm.PackageManager.PERMISSION_GRANTED; | |
19 | 22 | import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG; |
20 | 23 | import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; |
21 | 24 | import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; |
@@ -67,6 +70,8 @@ final class Session extends IWindowSession.Stub | ||
67 | 70 | final int mUid; |
68 | 71 | final int mPid; |
69 | 72 | final String mStringName; |
73 | + final boolean mCanAddInternalSystemWindow; | |
74 | + final boolean mCanHideNonSystemOverlayWindows; | |
70 | 75 | SurfaceSession mSurfaceSession; |
71 | 76 | int mNumWindow = 0; |
72 | 77 | boolean mClientDead = false; |
@@ -80,6 +85,10 @@ final class Session extends IWindowSession.Stub | ||
80 | 85 | mInputContext = inputContext; |
81 | 86 | mUid = Binder.getCallingUid(); |
82 | 87 | mPid = Binder.getCallingPid(); |
88 | + mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission( | |
89 | + INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED; | |
90 | + mCanHideNonSystemOverlayWindows = service.mContext.checkCallingOrSelfPermission( | |
91 | + HIDE_NON_SYSTEM_OVERLAY_WINDOWS) == PERMISSION_GRANTED; | |
83 | 92 | mLastReportedAnimatorScale = service.getCurrentAnimatorScale(); |
84 | 93 | StringBuilder sb = new StringBuilder(); |
85 | 94 | sb.append("Session{"); |
@@ -490,6 +490,9 @@ public class WindowManagerService extends IWindowManager.Stub | ||
490 | 490 | */ |
491 | 491 | final ArrayList<WindowState> mForceRemoves = new ArrayList<>(); |
492 | 492 | |
493 | + /** List of window currently causing non-system overlay windows to be hidden. */ | |
494 | + private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<WindowState>(); | |
495 | + | |
493 | 496 | /** |
494 | 497 | * Windows that clients are waiting to have drawn. |
495 | 498 | */ |
@@ -2129,6 +2132,9 @@ public class WindowManagerService extends IWindowManager.Stub | ||
2129 | 2132 | } |
2130 | 2133 | } |
2131 | 2134 | |
2135 | + final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty(); | |
2136 | + win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows); | |
2137 | + | |
2132 | 2138 | if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) { |
2133 | 2139 | token.appWindowToken.startingWindow = win; |
2134 | 2140 | if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + token.appWindowToken |
@@ -2576,6 +2582,7 @@ public class WindowManagerService extends IWindowManager.Stub | ||
2576 | 2582 | |
2577 | 2583 | mPendingRemove.remove(win); |
2578 | 2584 | mResizingWindows.remove(win); |
2585 | + updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */); | |
2579 | 2586 | mWindowsChanged = true; |
2580 | 2587 | if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win); |
2581 | 2588 |
@@ -11771,4 +11778,34 @@ public class WindowManagerService extends IWindowManager.Stub | ||
11771 | 11778 | } |
11772 | 11779 | } |
11773 | 11780 | } |
11781 | + | |
11782 | + void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) { | |
11783 | + if (!win.hideNonSystemOverlayWindowsWhenVisible()) { | |
11784 | + return; | |
11785 | + } | |
11786 | + final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty(); | |
11787 | + if (surfaceShown) { | |
11788 | + if (!mHidingNonSystemOverlayWindows.contains(win)) { | |
11789 | + mHidingNonSystemOverlayWindows.add(win); | |
11790 | + } | |
11791 | + } else { | |
11792 | + mHidingNonSystemOverlayWindows.remove(win); | |
11793 | + } | |
11794 | + | |
11795 | + final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty(); | |
11796 | + | |
11797 | + if (systemAlertWindowsHidden == hideSystemAlertWindows) { | |
11798 | + return; | |
11799 | + } | |
11800 | + | |
11801 | + final int numDisplays = mDisplayContents.size(); | |
11802 | + for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { | |
11803 | + final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); | |
11804 | + final int numWindows = windows.size(); | |
11805 | + for (int winNdx = 0; winNdx < numWindows; ++winNdx) { | |
11806 | + final WindowState w = windows.get(winNdx); | |
11807 | + w.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows); | |
11808 | + } | |
11809 | + } | |
11810 | + } | |
11774 | 11811 | } |
@@ -79,6 +79,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON; | ||
79 | 79 | import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; |
80 | 80 | import static android.view.WindowManager.LayoutParams.MATCH_PARENT; |
81 | 81 | import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; |
82 | +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; | |
82 | 83 | import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; |
83 | 84 | import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME; |
84 | 85 | import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH; |
@@ -91,7 +92,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION; | ||
91 | 92 | import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; |
92 | 93 | import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; |
93 | 94 | import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; |
95 | +import static android.view.WindowManager.LayoutParams.TYPE_TOAST; | |
94 | 96 | import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; |
97 | +import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; | |
95 | 98 | import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; |
96 | 99 | import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER; |
97 | 100 | import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM; |
@@ -141,6 +144,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { | ||
141 | 144 | final int mAppOp; |
142 | 145 | // UserId and appId of the owner. Don't display windows of non-current user. |
143 | 146 | final int mOwnerUid; |
147 | + final boolean mOwnerCanAddInternalSystemWindow; | |
144 | 148 | final IWindowId mWindowId; |
145 | 149 | WindowToken mToken; |
146 | 150 | WindowToken mRootToken; |
@@ -167,6 +171,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { | ||
167 | 171 | boolean mPolicyVisibilityAfterAnim = true; |
168 | 172 | boolean mAppOpVisibility = true; |
169 | 173 | boolean mPermanentlyHidden; // the window should never be shown again |
174 | + // This is a non-system overlay window that is currently force hidden. | |
175 | + private boolean mForceHideNonSystemOverlayWindow; | |
170 | 176 | boolean mAppFreezing; |
171 | 177 | boolean mAttachedHidden; // is our parent window hidden? |
172 | 178 | boolean mWallpaperVisible; // for wallpaper, what was last vis report? |
@@ -522,6 +528,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { | ||
522 | 528 | mAppOp = appOp; |
523 | 529 | mToken = token; |
524 | 530 | mOwnerUid = s.mUid; |
531 | + mOwnerCanAddInternalSystemWindow = s.mCanAddInternalSystemWindow; | |
525 | 532 | mWindowId = new IWindowId.Stub() { |
526 | 533 | @Override |
527 | 534 | public void registerFocusObserver(IWindowFocusObserver observer) { |
@@ -1882,6 +1889,10 @@ final class WindowState implements WindowManagerPolicy.WindowState { | ||
1882 | 1889 | // to handle their windows being removed from under them. |
1883 | 1890 | return false; |
1884 | 1891 | } |
1892 | + if (mForceHideNonSystemOverlayWindow) { | |
1893 | + // This is an alert window that is currently force hidden. | |
1894 | + return false; | |
1895 | + } | |
1885 | 1896 | if (mPolicyVisibility && mPolicyVisibilityAfterAnim) { |
1886 | 1897 | // Already showing. |
1887 | 1898 | return false; |
@@ -1955,6 +1966,22 @@ final class WindowState implements WindowManagerPolicy.WindowState { | ||
1955 | 1966 | return true; |
1956 | 1967 | } |
1957 | 1968 | |
1969 | + void setForceHideNonSystemOverlayWindowIfNeeded(boolean forceHide) { | |
1970 | + if (mOwnerCanAddInternalSystemWindow | |
1971 | + || (!isSystemAlertWindowType(mAttrs.type) && mAttrs.type != TYPE_TOAST)) { | |
1972 | + return; | |
1973 | + } | |
1974 | + if (mForceHideNonSystemOverlayWindow == forceHide) { | |
1975 | + return; | |
1976 | + } | |
1977 | + mForceHideNonSystemOverlayWindow = forceHide; | |
1978 | + if (forceHide) { | |
1979 | + hideLw(true /* doAnimation */, true /* requestAnim */); | |
1980 | + } else { | |
1981 | + showLw(true /* doAnimation */, true /* requestAnim */); | |
1982 | + } | |
1983 | + } | |
1984 | + | |
1958 | 1985 | public void setAppOpVisibilityLw(boolean state) { |
1959 | 1986 | if (mAppOpVisibility != state) { |
1960 | 1987 | mAppOpVisibility = state; |
@@ -2755,6 +2782,17 @@ final class WindowState implements WindowManagerPolicy.WindowState { | ||
2755 | 2782 | } |
2756 | 2783 | } |
2757 | 2784 | |
2785 | + /** | |
2786 | + * Returns true if any window added by an application process that if of type | |
2787 | + * {@link android.view.WindowManager.LayoutParams#TYPE_TOAST} or that requires that requires | |
2788 | + * {@link android.app.AppOpsManager#OP_SYSTEM_ALERT_WINDOW} permission should be hidden when | |
2789 | + * this window is visible. | |
2790 | + */ | |
2791 | + boolean hideNonSystemOverlayWindowsWhenVisible() { | |
2792 | + return (mAttrs.privateFlags & PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0 | |
2793 | + && mSession.mCanHideNonSystemOverlayWindows; | |
2794 | + } | |
2795 | + | |
2758 | 2796 | String makeInputChannelName() { |
2759 | 2797 | return Integer.toHexString(System.identityHashCode(this)) |
2760 | 2798 | + " " + getWindowTag(); |
@@ -582,6 +582,7 @@ class WindowStateAnimator { | ||
582 | 582 | //dump(); |
583 | 583 | mLastHidden = true; |
584 | 584 | if (mSurfaceController != null) { |
585 | + mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mWin, false); | |
585 | 586 | mSurfaceController.hideInTransaction(reason); |
586 | 587 | } |
587 | 588 | } |
@@ -1814,6 +1815,7 @@ class WindowStateAnimator { | ||
1814 | 1815 | if (!shown) |
1815 | 1816 | return false; |
1816 | 1817 | |
1818 | + mService.updateNonSystemOverlayWindowsVisibilityIfNeeded(mWin, true); | |
1817 | 1819 | if (mWin.mTurnOnScreen) { |
1818 | 1820 | if (DEBUG_VISIBILITY) Slog.v(TAG, "Show surface turning screen on: " + mWin); |
1819 | 1821 | mWin.mTurnOnScreen = false; |
@@ -71,6 +71,7 @@ import android.content.pm.PackageManager; | ||
71 | 71 | import android.content.pm.PackageManager.NameNotFoundException; |
72 | 72 | import android.content.pm.PackageManagerInternal; |
73 | 73 | import android.content.pm.ParceledListSlice; |
74 | +import android.content.pm.PermissionInfo; | |
74 | 75 | import android.content.pm.ResolveInfo; |
75 | 76 | import android.content.pm.ServiceInfo; |
76 | 77 | import android.content.pm.UserInfo; |
@@ -123,6 +124,7 @@ import android.telephony.TelephonyManager; | ||
123 | 124 | import android.text.TextUtils; |
124 | 125 | import android.util.ArrayMap; |
125 | 126 | import android.util.ArraySet; |
127 | +import android.util.EventLog; | |
126 | 128 | import android.util.Log; |
127 | 129 | import android.util.Pair; |
128 | 130 | import android.util.Slog; |
@@ -8621,6 +8623,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { | ||
8621 | 8623 | < android.os.Build.VERSION_CODES.M) { |
8622 | 8624 | return false; |
8623 | 8625 | } |
8626 | + if (!isRuntimePermission(permission)) { | |
8627 | + EventLog.writeEvent(0x534e4554, "62623498", user.getIdentifier(), ""); | |
8628 | + return false; | |
8629 | + } | |
8624 | 8630 | final PackageManager packageManager = mContext.getPackageManager(); |
8625 | 8631 | switch (grantState) { |
8626 | 8632 | case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: { |
@@ -8646,12 +8652,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { | ||
8646 | 8652 | return true; |
8647 | 8653 | } catch (SecurityException se) { |
8648 | 8654 | return false; |
8655 | + } catch (NameNotFoundException e) { | |
8656 | + return false; | |
8649 | 8657 | } finally { |
8650 | 8658 | mInjector.binderRestoreCallingIdentity(ident); |
8651 | 8659 | } |
8652 | 8660 | } |
8653 | 8661 | } |
8654 | 8662 | |
8663 | + public boolean isRuntimePermission(String permissionName) throws NameNotFoundException { | |
8664 | + final PackageManager packageManager = mContext.getPackageManager(); | |
8665 | + PermissionInfo permissionInfo = packageManager.getPermissionInfo(permissionName, 0); | |
8666 | + return (permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) | |
8667 | + == PermissionInfo.PROTECTION_DANGEROUS; | |
8668 | + } | |
8669 | + | |
8655 | 8670 | @Override |
8656 | 8671 | public int getPermissionGrantState(ComponentName admin, String packageName, |
8657 | 8672 | String permission) throws RemoteException { |