/*
 * Copyright (C) 2022 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 android.security.cts.CVE_2021_0954;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;

public class PocService extends Service {
    Button mButton;
    WindowManager mWindowManager;

    private int getScreenWidth() {
        return Resources.getSystem().getDisplayMetrics().widthPixels;
    }

    private int getScreenHeight() {
        return Resources.getSystem().getDisplayMetrics().heightPixels;
    }

    String getStringRes(int key) {
        return getResources().getString(key);
    }

    int getIntegerRes(int key) {
        return getResources().getInteger(key);
    }

    @Override
    public void onCreate() {
        try {
            super.onCreate();
            mWindowManager = getSystemService(WindowManager.class);
            LayoutParams layoutParams = new LayoutParams();
            layoutParams.type = LayoutParams.TYPE_APPLICATION_OVERLAY;
            layoutParams.flags =
                    LayoutParams.FLAG_NOT_TOUCH_MODAL | LayoutParams.FLAG_NOT_FOCUSABLE;
            layoutParams.format = PixelFormat.OPAQUE;
            layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
            layoutParams.width = getScreenWidth();
            layoutParams.height = getScreenHeight();
            layoutParams.x = getScreenWidth() / 2;
            layoutParams.y = getScreenHeight() / 2;

            /* Show the floating window */
            mButton = new Button(this);
            mButton.setText(getString(R.string.overlayButtonText));
            mWindowManager.addView(mButton, layoutParams);
        } catch (Exception e) {
            sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
            return;
        }
        sendTestResult(getIntegerRes(R.integer.noAssumptionFailure), getStringRes(R.string.empty));
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        try {
            if (mWindowManager != null && mButton != null) {
                mWindowManager.removeView(mButton);
            }
            super.onDestroy();
        } catch (Exception e) {
            sendTestResult(getIntegerRes(R.integer.assumptionFailure), e.getMessage());
        }
    }

    private void sendTestResult(int result, String message) {
        try {
            SharedPreferences sh = getSharedPreferences(getStringRes(R.string.sharedPreferences),
                    Context.MODE_PRIVATE);
            SharedPreferences.Editor edit = sh.edit();
            edit.putInt(getStringRes(R.string.resultKey), result);
            edit.putString(getStringRes(R.string.messageKey), message);
            edit.commit();
        } catch (Exception e) {
            // ignore the exception
        }
    }
}
