/*
 * Copyright (C) 2018 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.appprediction;

import static android.Manifest.permission.MANAGE_APP_PREDICTIONS;
import static android.Manifest.permission.PACKAGE_USAGE_STATS;
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.content.Context.APP_PREDICTION_SERVICE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionSessionId;
import android.app.prediction.AppTargetEvent;
import android.app.prediction.IPredictionCallback;
import android.app.prediction.IPredictionManager;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.Binder;
import android.os.IBinder;
import android.os.Process;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.util.Slog;

import com.android.server.LocalServices;
import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.FrameworkResourcesServiceNameResolver;
import com.android.server.wm.ActivityTaskManagerInternal;

import java.io.FileDescriptor;
import java.util.function.Consumer;

/**
 * A service used to predict app and shortcut usage.
 *
 * <p>The data collected by this service can be analyzed and combined with other sources to provide
 * predictions in different areas of the system such as Launcher and Share sheet.
 */
public class AppPredictionManagerService extends
        AbstractMasterSystemService<AppPredictionManagerService, AppPredictionPerUserService> {

    private static final String TAG = AppPredictionManagerService.class.getSimpleName();

    private static final int MAX_TEMP_SERVICE_DURATION_MS = 1_000 * 60 * 2; // 2 minutes

    private ActivityTaskManagerInternal mActivityTaskManagerInternal;

    public AppPredictionManagerService(Context context) {
        super(context, new FrameworkResourcesServiceNameResolver(context,
                com.android.internal.R.string.config_defaultAppPredictionService), null,
                PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
        mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
    }

    @Override
    protected AppPredictionPerUserService newServiceLocked(int resolvedUserId, boolean disabled) {
        return new AppPredictionPerUserService(this, mLock, resolvedUserId);
    }

    @Override
    public void onStart() {
        publishBinderService(APP_PREDICTION_SERVICE, new PredictionManagerServiceStub());
    }

    @Override
    protected void enforceCallingPermissionForManagement() {
        getContext().enforceCallingPermission(MANAGE_APP_PREDICTIONS, TAG);
    }

    @Override // from AbstractMasterSystemService
    protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
        final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
        if (service != null) {
            service.onPackageUpdatedLocked();
        }
    }

    @Override // from AbstractMasterSystemService
    protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
        final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
        if (service != null) {
            service.onPackageRestartedLocked();
        }
    }

    @Override
    protected int getMaximumTemporaryServiceDurationMs() {
        return MAX_TEMP_SERVICE_DURATION_MS;
    }

    private class PredictionManagerServiceStub extends IPredictionManager.Stub {

        @Override
        public void createPredictionSession(@NonNull AppPredictionContext context,
                @NonNull AppPredictionSessionId sessionId, @NonNull IBinder token) {
            runForUserLocked("createPredictionSession", sessionId, (service) ->
                    service.onCreatePredictionSessionLocked(context, sessionId, token));
        }

        @Override
        public void notifyAppTargetEvent(@NonNull AppPredictionSessionId sessionId,
                @NonNull AppTargetEvent event) {
            runForUserLocked("notifyAppTargetEvent", sessionId,
                    (service) -> service.notifyAppTargetEventLocked(sessionId, event));
        }

        @Override
        public void notifyLaunchLocationShown(@NonNull AppPredictionSessionId sessionId,
                @NonNull String launchLocation, @NonNull ParceledListSlice targetIds) {
            runForUserLocked("notifyLaunchLocationShown", sessionId, (service) ->
                    service.notifyLaunchLocationShownLocked(sessionId, launchLocation, targetIds));
        }

        @Override
        public void sortAppTargets(@NonNull AppPredictionSessionId sessionId,
                @NonNull ParceledListSlice targets,
                IPredictionCallback callback) {
            runForUserLocked("sortAppTargets", sessionId,
                    (service) -> service.sortAppTargetsLocked(sessionId, targets, callback));
        }

        @Override
        public void registerPredictionUpdates(@NonNull AppPredictionSessionId sessionId,
                @NonNull IPredictionCallback callback) {
            runForUserLocked("registerPredictionUpdates", sessionId,
                    (service) -> service.registerPredictionUpdatesLocked(sessionId, callback));
        }

        public void unregisterPredictionUpdates(@NonNull AppPredictionSessionId sessionId,
                @NonNull IPredictionCallback callback) {
            runForUserLocked("unregisterPredictionUpdates", sessionId,
                    (service) -> service.unregisterPredictionUpdatesLocked(sessionId, callback));
        }

        @Override
        public void requestPredictionUpdate(@NonNull AppPredictionSessionId sessionId) {
            runForUserLocked("requestPredictionUpdate", sessionId,
                    (service) -> service.requestPredictionUpdateLocked(sessionId));
        }

        @Override
        public void onDestroyPredictionSession(@NonNull AppPredictionSessionId sessionId) {
            runForUserLocked("onDestroyPredictionSession", sessionId,
                    (service) -> service.onDestroyPredictionSessionLocked(sessionId));
        }

        public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
                @Nullable FileDescriptor err,
                @NonNull String[] args, @Nullable ShellCallback callback,
                @NonNull ResultReceiver resultReceiver) {
            new AppPredictionManagerServiceShellCommand(AppPredictionManagerService.this)
                    .exec(this, in, out, err, args, callback, resultReceiver);
        }

        private void runForUserLocked(@NonNull final String func,
                @NonNull final AppPredictionSessionId sessionId,
                @NonNull final Consumer<AppPredictionPerUserService> c) {
            ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class);
            final int userId = am.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                    sessionId.getUserId(), false, ALLOW_NON_FULL, null, null);

            Context ctx = getContext();
            if (!(ctx.checkCallingPermission(PACKAGE_USAGE_STATS) == PERMISSION_GRANTED
                    || mServiceNameResolver.isTemporary(userId)
                    || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())
                    || Binder.getCallingUid() == Process.SYSTEM_UID)) {

                String msg = "Permission Denial: " + func + " from pid="
                        + Binder.getCallingPid()
                        + ", uid=" + Binder.getCallingUid()
                        + " expected caller to hold PACKAGE_USAGE_STATS permission";
                Slog.w(TAG, msg);
                throw new SecurityException(msg);
            }

            final long origId = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
                    final AppPredictionPerUserService service = getServiceForUserLocked(userId);
                    c.accept(service);
                }
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
        }
    }
}
