/services/java/com/android/server/UpdateLockService.java

https://github.com/aizuzi/platform_frameworks_base · Java · 126 lines · 89 code · 18 blank · 19 comment · 6 complexity · a15a802ad1523caff5a589a99aa6021e MD5 · raw file

  1. /*
  2. * Copyright (C) 2012 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.android.server;
  17. import android.content.Context;
  18. import android.content.Intent;
  19. import android.content.pm.PackageManager;
  20. import android.os.Binder;
  21. import android.os.Handler;
  22. import android.os.IBinder;
  23. import android.os.IUpdateLock;
  24. import android.os.RemoteException;
  25. import android.os.SystemClock;
  26. import android.os.TokenWatcher;
  27. import android.os.UpdateLock;
  28. import android.os.UserHandle;
  29. import android.util.Slog;
  30. import java.io.FileDescriptor;
  31. import java.io.PrintWriter;
  32. public class UpdateLockService extends IUpdateLock.Stub {
  33. static final boolean DEBUG = false;
  34. static final String TAG = "UpdateLockService";
  35. // signatureOrSystem required to use update locks
  36. static final String PERMISSION = "android.permission.UPDATE_LOCK";
  37. Context mContext;
  38. LockWatcher mLocks;
  39. class LockWatcher extends TokenWatcher {
  40. LockWatcher(Handler h, String tag) {
  41. super(h, tag);
  42. }
  43. public void acquired() {
  44. if (DEBUG) {
  45. Slog.d(TAG, "first acquire; broadcasting convenient=false");
  46. }
  47. sendLockChangedBroadcast(false);
  48. }
  49. public void released() {
  50. if (DEBUG) {
  51. Slog.d(TAG, "last release; broadcasting convenient=true");
  52. }
  53. sendLockChangedBroadcast(true);
  54. }
  55. }
  56. UpdateLockService(Context context) {
  57. mContext = context;
  58. mLocks = new LockWatcher(new Handler(), "UpdateLocks");
  59. // Consider just-booting to be a reasonable time to allow
  60. // interruptions for update installation etc.
  61. sendLockChangedBroadcast(true);
  62. }
  63. void sendLockChangedBroadcast(boolean state) {
  64. // Safe early during boot because this broadcast only goes to registered receivers.
  65. long oldIdent = Binder.clearCallingIdentity();
  66. try {
  67. Intent intent = new Intent(UpdateLock.UPDATE_LOCK_CHANGED)
  68. .putExtra(UpdateLock.NOW_IS_CONVENIENT, state)
  69. .putExtra(UpdateLock.TIMESTAMP, System.currentTimeMillis())
  70. .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
  71. mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
  72. } finally {
  73. Binder.restoreCallingIdentity(oldIdent);
  74. }
  75. }
  76. @Override
  77. public void acquireUpdateLock(IBinder token, String tag) throws RemoteException {
  78. if (DEBUG) {
  79. Slog.d(TAG, "acquire(" + token + ") by " + makeTag(tag));
  80. }
  81. mContext.enforceCallingOrSelfPermission(PERMISSION, "acquireUpdateLock");
  82. mLocks.acquire(token, makeTag(tag));
  83. }
  84. @Override
  85. public void releaseUpdateLock(IBinder token) throws RemoteException {
  86. if (DEBUG) {
  87. Slog.d(TAG, "release(" + token + ')');
  88. }
  89. mContext.enforceCallingOrSelfPermission(PERMISSION, "releaseUpdateLock");
  90. mLocks.release(token);
  91. };
  92. private String makeTag(String tag) {
  93. return "{tag=" + tag
  94. + " uid=" + Binder.getCallingUid()
  95. + " pid=" + Binder.getCallingPid() + '}';
  96. }
  97. @Override
  98. public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
  99. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
  100. != PackageManager.PERMISSION_GRANTED) {
  101. pw.println("Permission Denial: can't dump update lock service from from pid="
  102. + Binder.getCallingPid()
  103. + ", uid=" + Binder.getCallingUid());
  104. return;
  105. }
  106. mLocks.dump(pw);
  107. }
  108. }