diff options
| author | 2019-07-19 14:24:52 -0700 | |
|---|---|---|
| committer | 2019-07-19 14:24:52 -0700 | |
| commit | e5786b7ab8991d559ca2dab758e0e8a7be2f84e0 (patch) | |
| tree | c1ba5f34e36daa3b89c107940a8c2c3f2c2f2027 | |
| parent | a50e7bb20dc75c865ea0b535a34090700b9db318 (diff) | |
| parent | 4b09d08c6c26bff1406b5785dd9942c764ffce49 (diff) | |
Merge "Revert "Stop idmap2d after several seconds pass"" into qt-r1-dev
am: 4b09d08c6c
Change-Id: I7e6d5d4f5245319fc3fcbfe27c16f11ad80eb9c2
3 files changed, 49 insertions, 204 deletions
diff --git a/services/core/java/com/android/server/om/IdmapDaemon.java b/services/core/java/com/android/server/om/IdmapDaemon.java deleted file mode 100644 index 55fbcb4344cf..000000000000 --- a/services/core/java/com/android/server/om/IdmapDaemon.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2019 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.server.om; - -import static android.content.Context.IDMAP_SERVICE; - -import static com.android.server.om.OverlayManagerService.DEBUG; -import static com.android.server.om.OverlayManagerService.TAG; - -import android.os.IBinder; -import android.os.IIdmap2; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemProperties; -import android.util.Slog; - -import com.android.server.IoThread; - -import java.util.concurrent.FutureTask; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * To prevent idmap2d from continuously running, the idmap daemon will terminate after 10 - * seconds without a transaction. - **/ -class IdmapDaemon { - // The amount of time in milliseconds to wait after a transaction to the idmap service is made - // before stopping the service. - private static final int SERVICE_TIMEOUT_MS = 10000; - - // The amount of time in milliseconds to wait when attempting to connect to idmap service. - private static final int SERVICE_CONNECT_TIMEOUT_MS = 5000; - - private static final Object IDMAP_TOKEN = new Object(); - private static final String IDMAP_DAEMON = "idmap2d"; - - private static IdmapDaemon sInstance; - private volatile IIdmap2 mService; - private final AtomicInteger mOpenedCount = new AtomicInteger(); - - /** - * An {@link AutoCloseable} connection to the idmap service. When the connection is closed or - * finalized, the idmap service will be stopped after a period of time unless another connection - * to the service is open. - **/ - private class Connection implements AutoCloseable { - private boolean mOpened = true; - - private Connection() { - synchronized (IDMAP_TOKEN) { - mOpenedCount.incrementAndGet(); - } - } - - @Override - public void close() { - synchronized (IDMAP_TOKEN) { - if (!mOpened) { - return; - } - - mOpened = false; - if (mOpenedCount.decrementAndGet() != 0) { - // Only post the callback to stop the service if the service does not have an - // open connection. - return; - } - - IoThread.getHandler().postDelayed(() -> { - synchronized (IDMAP_TOKEN) { - // Only stop the service if the service does not have an open connection. - if (mService == null || mOpenedCount.get() != 0) { - return; - } - - stopIdmapService(); - mService = null; - } - }, IDMAP_TOKEN, SERVICE_TIMEOUT_MS); - } - } - } - - static IdmapDaemon getInstance() { - if (sInstance == null) { - sInstance = new IdmapDaemon(); - } - return sInstance; - } - - String createIdmap(String targetPath, String overlayPath, int policies, boolean enforce, - int userId) throws Exception { - try (Connection connection = connect()) { - return mService.createIdmap(targetPath, overlayPath, policies, enforce, userId); - } - } - - boolean removeIdmap(String overlayPath, int userId) throws Exception { - try (Connection connection = connect()) { - return mService.removeIdmap(overlayPath, userId); - } - } - - boolean verifyIdmap(String overlayPath, int policies, boolean enforce, int userId) - throws Exception { - try (Connection connection = connect()) { - return mService.verifyIdmap(overlayPath, policies, enforce, userId); - } - } - - String getIdmapPath(String overlayPath, int userId) throws Exception { - try (Connection connection = connect()) { - return mService.getIdmapPath(overlayPath, userId); - } - } - - static void startIdmapService() { - SystemProperties.set("ctl.start", IDMAP_DAEMON); - } - - static void stopIdmapService() { - SystemProperties.set("ctl.stop", IDMAP_DAEMON); - } - - private Connection connect() throws Exception { - synchronized (IDMAP_TOKEN) { - IoThread.getHandler().removeCallbacksAndMessages(IDMAP_TOKEN); - if (mService != null) { - // Not enough time has passed to stop the idmap service. Reuse the existing - // interface. - return new Connection(); - } - - // Start the idmap service if it is not currently running. - startIdmapService(); - - // Block until the service is found. - FutureTask<IBinder> bindIdmap = new FutureTask<>(() -> { - IBinder binder = null; - while (binder == null) { - try { - binder = ServiceManager.getService(IDMAP_SERVICE); - Thread.sleep(100); - } catch (Exception e) { - Slog.e(TAG, "service '" + IDMAP_SERVICE + "' not retrieved; " - + e.getMessage()); - } - } - return binder; - }); - - IBinder binder; - try { - IoThread.getHandler().postAtFrontOfQueue(bindIdmap); - binder = bindIdmap.get(SERVICE_CONNECT_TIMEOUT_MS, TimeUnit.MILLISECONDS); - } catch (Exception rethrow) { - Slog.e(TAG, "service '" + IDMAP_SERVICE + "' not found;"); - throw rethrow; - } - - try { - binder.linkToDeath(() -> { - Slog.w(TAG, "service '" + IDMAP_SERVICE + "' died"); - }, 0); - } catch (RemoteException rethrow) { - Slog.e(TAG, "service '" + IDMAP_SERVICE + "' failed to be bound"); - throw rethrow; - } - - mService = IIdmap2.Stub.asInterface(binder); - if (DEBUG) { - Slog.d(TAG, "service '" + IDMAP_SERVICE + "' connected"); - } - - return new Connection(); - } - } -} diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java index 9b6d986d90d2..b604aa87f8f3 100644 --- a/services/core/java/com/android/server/om/IdmapManager.java +++ b/services/core/java/com/android/server/om/IdmapManager.java @@ -16,6 +16,9 @@ package com.android.server.om; +import static android.content.Context.IDMAP_SERVICE; +import static android.text.format.DateUtils.SECOND_IN_MILLIS; + import static com.android.server.om.OverlayManagerService.DEBUG; import static com.android.server.om.OverlayManagerService.TAG; @@ -24,11 +27,15 @@ import android.content.om.OverlayInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.os.Build.VERSION_CODES; +import android.os.IBinder; import android.os.IIdmap2; +import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.util.Slog; +import com.android.internal.os.BackgroundThread; import com.android.server.om.OverlayManagerServiceImpl.PackageManagerHelper; import com.android.server.pm.Installer; @@ -44,6 +51,11 @@ import java.io.File; */ class IdmapManager { private static final boolean FEATURE_FLAG_IDMAP2 = true; + + private final Installer mInstaller; + private final PackageManagerHelper mPackageManager; + private IIdmap2 mIdmap2Service; + private static final boolean VENDOR_IS_Q_OR_LATER; static { final String value = SystemProperties.get("ro.vndk.version", "29"); @@ -58,14 +70,12 @@ class IdmapManager { VENDOR_IS_Q_OR_LATER = isQOrLater; } - private final Installer mInstaller; - private final PackageManagerHelper mPackageManager; - private final IdmapDaemon mIdmapDaemon; - IdmapManager(final Installer installer, final PackageManagerHelper packageManager) { mInstaller = installer; mPackageManager = packageManager; - mIdmapDaemon = IdmapDaemon.getInstance(); + if (FEATURE_FLAG_IDMAP2) { + connectToIdmap2d(); + } } boolean createIdmap(@NonNull final PackageInfo targetPackage, @@ -81,11 +91,11 @@ class IdmapManager { if (FEATURE_FLAG_IDMAP2) { int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId); boolean enforce = enforceOverlayable(overlayPackage); - if (mIdmapDaemon.verifyIdmap(overlayPath, policies, enforce, userId)) { + if (mIdmap2Service.verifyIdmap(overlayPath, policies, enforce, userId)) { return true; } - return mIdmapDaemon.createIdmap(targetPath, overlayPath, policies, - enforce, userId) != null; + return mIdmap2Service.createIdmap(targetPath, overlayPath, policies, enforce, + userId) != null; } else { mInstaller.idmap(targetPath, overlayPath, sharedGid); return true; @@ -103,7 +113,7 @@ class IdmapManager { } try { if (FEATURE_FLAG_IDMAP2) { - return mIdmapDaemon.removeIdmap(oi.baseCodePath, userId); + return mIdmap2Service.removeIdmap(oi.baseCodePath, userId); } else { mInstaller.removeIdmap(oi.baseCodePath); return true; @@ -127,7 +137,7 @@ class IdmapManager { final int userId) { if (FEATURE_FLAG_IDMAP2) { try { - return mIdmapDaemon.getIdmapPath(overlayPackagePath, userId); + return mIdmap2Service.getIdmapPath(overlayPackagePath, userId); } catch (Exception e) { Slog.w(TAG, "failed to get idmap path for " + overlayPackagePath + ": " + e.getMessage()); @@ -141,6 +151,35 @@ class IdmapManager { } } + private void connectToIdmap2d() { + IBinder binder = ServiceManager.getService(IDMAP_SERVICE); + if (binder != null) { + try { + binder.linkToDeath(new IBinder.DeathRecipient() { + @Override + public void binderDied() { + Slog.w(TAG, "service '" + IDMAP_SERVICE + "' died; reconnecting..."); + connectToIdmap2d(); + } + + }, 0); + } catch (RemoteException e) { + binder = null; + } + } + if (binder != null) { + mIdmap2Service = IIdmap2.Stub.asInterface(binder); + if (DEBUG) { + Slog.d(TAG, "service '" + IDMAP_SERVICE + "' connected"); + } + } else { + Slog.w(TAG, "service '" + IDMAP_SERVICE + "' not found; trying again..."); + BackgroundThread.getHandler().postDelayed(() -> { + connectToIdmap2d(); + }, SECOND_IN_MILLIS); + } + } + /** * Checks if overlayable and policies should be enforced on the specified overlay for backwards * compatibility with pre-Q overlays. diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index ce951816d3a6..da69986cd59f 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -262,7 +262,6 @@ public final class OverlayManagerService extends SystemService { initIfNeeded(); onSwitchUser(UserHandle.USER_SYSTEM); - IdmapDaemon.stopIdmapService(); publishBinderService(Context.OVERLAY_SERVICE, mService); publishLocalService(OverlayManagerService.class, this); |