Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6c1e6ab authored by Priyank Singh's avatar Priyank Singh
Browse files

DO NOT MERGE Revert "Adding the privacy chip to the CarStatusBar"

This reverts commit 5bd57677.

Reason for revert: We want to delete all the code related to privacy chip/indicator from Q as of now. b/132292477

Bug: 133898491
Change-Id: Ieddae7509d918ab63a5b3111e0efc623fae644b3
parent 5bd57677
Loading
Loading
Loading
Loading
+0 −37
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     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.
-->

<com.android.systemui.statusbar.car.privacy.OngoingPrivacyChip
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/car_privacy_chip"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_margin="@dimen/ongoing_appops_chip_margin"
    android:layout_toStartOf="@+id/clock_container"
    android:focusable="true"
    android:gravity="center_vertical|end"
    android:orientation="horizontal"
    android:paddingEnd="@dimen/ongoing_appops_chip_side_padding"
    android:paddingStart="@dimen/ongoing_appops_chip_side_padding"
    android:visibility="visible">

    <LinearLayout
        android:id="@+id/icons_container"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical|start"/>
</com.android.systemui.statusbar.car.privacy.OngoingPrivacyChip>
 No newline at end of file
+0 −2
Original line number Diff line number Diff line
@@ -65,8 +65,6 @@
            />
        </FrameLayout>

        <include layout="@layout/car_ongoing_privacy_chip"/>

        <FrameLayout
            android:id="@+id/clock_container"
            android:layout_width="wrap_content"
+0 −20
Original line number Diff line number Diff line
@@ -59,16 +59,6 @@
    <dimen name="car_keyline_1">24dp</dimen>
    <dimen name="car_keyline_2">96dp</dimen>
    <dimen name="car_keyline_3">128dp</dimen>
    <dimen name="privacy_chip_icon_height">36dp</dimen>
    <dimen name="privacy_chip_icon_padding_left">0dp</dimen>
    <dimen name="privacy_chip_icon_padding_right">0dp</dimen>
    <dimen name="privacy_chip_icon_padding_top">0dp</dimen>
    <dimen name="privacy_chip_icon_padding_bottom">0dp</dimen>

    <dimen name="privacy_chip_text_padding_left">0dp</dimen>
    <dimen name="privacy_chip_text_padding_right">0dp</dimen>
    <dimen name="privacy_chip_text_padding_top">0dp</dimen>
    <dimen name="privacy_chip_text_padding_bottom">0dp</dimen>

    <dimen name="privacy_chip_icon_max_height">100dp</dimen>

@@ -86,16 +76,6 @@
    <dimen name="ongoing_appops_chip_bg_padding">4dp</dimen>
    <!-- Radius of Ongoing App Ops chip corners -->
    <dimen name="ongoing_appops_chip_bg_corner_radius">12dp</dimen>
    <!-- Start padding for the app icon displayed in the dialog -->
    <dimen name="privacy_dialog_app_icon_padding_start">40dp</dimen>
    <!-- End padding for the app opps icon displayed in the dialog -->
    <dimen name="privacy_dialog_app_ops_icon_padding_end">40dp</dimen>
    <!-- Top padding for the list of application displayed in the dialog -->
    <dimen name="privacy_dialog_app_list_padding_top">20dp</dimen>
    <!-- Top padding for the dialog container-->
    <dimen name="privacy_dialog_container_padding_top">10dp</dimen>
    <!-- Top padding for the dialog title-->
    <dimen name="privacy_dialog_title_padding_start">10dp</dimen>

    <!-- Car volume dimens. -->
    <dimen name="car_volume_item_height">@*android:dimen/car_single_line_list_item_height</dimen>
+0 −228
Original line number Diff line number Diff line
/*
 * 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.systemui.statusbar.car.privacy;

import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.appops.AppOpItem;
import com.android.systemui.appops.AppOpsController;
import com.android.systemui.plugins.ActivityStarter;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Layout defining the privacy chip that will be displayed in CarStatusRar with the information for
 * which applications are using AppOpps permission fpr camera, mic and location.
 */
public class OngoingPrivacyChip extends LinearLayout implements View.OnClickListener {

    private Context mContext;

    private LinearLayout mIconsContainer;
    private List<PrivacyItem> mPrivacyItems;
    private static AppOpsController sAppOpsController;
    private UserManager mUserManager;
    private int mCurrentUser;
    private List<Integer> mCurrentUserIds;
    private boolean mListening = false;
    PrivacyDialogBuilder mPrivacyDialogBuilder;
    private LinearLayout mPrivacyChip;
    private ActivityStarter mActivityStarter;

    protected static final int[] OPS = new int[]{
            AppOpsManager.OP_CAMERA,
            AppOpsManager.OP_RECORD_AUDIO,
            AppOpsManager.OP_COARSE_LOCATION,
            AppOpsManager.OP_FINE_LOCATION
    };

    public OngoingPrivacyChip(Context context) {
        super(context, null);
        init(context);
    }

    public OngoingPrivacyChip(Context context, AttributeSet attr) {
        super(context, attr);
        init(context);
    }

    public OngoingPrivacyChip(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
        init(context);
    }

    public OngoingPrivacyChip(Context context, AttributeSet attr, int defStyle, int a) {
        super(context, attr, defStyle, a);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mPrivacyItems = new ArrayList<>();
        sAppOpsController = Dependency.get(AppOpsController.class);
        mUserManager = mContext.getSystemService(UserManager.class);
        mActivityStarter = Dependency.get(ActivityStarter.class);
        mCurrentUser = ActivityManager.getCurrentUser();
        mCurrentUserIds = mUserManager.getProfiles(mCurrentUser).stream().map(
                userInfo -> userInfo.id).collect(Collectors.toList());

        mPrivacyDialogBuilder = new PrivacyDialogBuilder(context, mPrivacyItems);
    }

    private AppOpsController.Callback mCallback = new AppOpsController.Callback() {

        @Override
        public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
            int userId = UserHandle.getUserId(uid);
            if (mCurrentUserIds.contains(userId)) {
                updatePrivacyList();
            }
        }
    };

    @Override
    public void onFinishInflate() {
        mIconsContainer = findViewById(R.id.icons_container);
        mPrivacyChip = (LinearLayout) findViewById(R.id.car_privacy_chip);
        if (mPrivacyChip != null) {
            mPrivacyChip.setOnClickListener(this);
            setListening(true);
        }
    }

    @Override
    public void onDetachedFromWindow() {
        if (mPrivacyChip != null) {
            setListening(false);
        }
        super.onDetachedFromWindow();
    }

    @Override
    public void onClick(View v) {
        updatePrivacyList();
        Handler mUiHandler = new Handler(Looper.getMainLooper());
        mUiHandler.post(() -> {
            mActivityStarter.postStartActivityDismissingKeyguard(
                    new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0);
        });
    }

    private void setListening(boolean listen) {
        if (mListening == listen) {
            return;
        }
        mListening = listen;
        if (mListening) {
            sAppOpsController.addCallback(OPS, mCallback);
            updatePrivacyList();
        } else {
            sAppOpsController.removeCallback(OPS, mCallback);
        }
    }

    private void updatePrivacyList() {
        mPrivacyItems = mCurrentUserIds.stream()
                .flatMap(item -> sAppOpsController.getActiveAppOpsForUser(item).stream())
                .filter(Objects::nonNull)
                .map(item -> toPrivacyItem(item))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        mPrivacyDialogBuilder = new PrivacyDialogBuilder(mContext, mPrivacyItems);

        Handler refresh = new Handler(Looper.getMainLooper());
        refresh.post(new Runnable() {
            @Override
            public void run() {
                updateView();
            }
        });
    }

    private PrivacyItem toPrivacyItem(AppOpItem appOpItem) {
        PrivacyType type;
        switch (appOpItem.getCode()) {
            case AppOpsManager.OP_CAMERA:
                type = PrivacyType.TYPE_CAMERA;
                break;
            case AppOpsManager.OP_COARSE_LOCATION:
                type = PrivacyType.TYPE_LOCATION;
                break;
            case AppOpsManager.OP_FINE_LOCATION:
                type = PrivacyType.TYPE_LOCATION;
                break;
            case AppOpsManager.OP_RECORD_AUDIO:
                type = PrivacyType.TYPE_MICROPHONE;
                break;
            default:
                return null;
        }
        PrivacyApplication app = new PrivacyApplication(appOpItem.getPackageName(), mContext);
        return new PrivacyItem(type, app, appOpItem.getTimeStarted());
    }

    // Should only be called if the mPrivacyDialogBuilder icons or app changed
    private void updateView() {
        if (mPrivacyItems.isEmpty()) {
            mPrivacyChip.setVisibility(GONE);
            return;
        }
        mPrivacyChip.setVisibility(VISIBLE);
        setIcons(mPrivacyDialogBuilder);

        requestLayout();
    }

    private void setIcons(PrivacyDialogBuilder dialogBuilder) {
        mIconsContainer.removeAllViews();
        dialogBuilder.generateIcons().forEach(item -> {
            int size = mContext.getResources().getDimensionPixelSize(
                    R.dimen.privacy_chip_icon_height);
            ImageView image = new ImageView(mContext);
            image.setImageDrawable(item);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(size, size);

            int leftPadding = mContext.getResources().getDimensionPixelSize(
                    R.dimen.privacy_chip_icon_padding_left);
            int topPadding = mContext.getResources().getDimensionPixelSize(
                    R.dimen.privacy_chip_icon_padding_top);
            int rightPadding = mContext.getResources().getDimensionPixelSize(
                    R.dimen.privacy_chip_icon_padding_right);
            int bottomPadding = mContext.getResources().getDimensionPixelSize(
                    R.dimen.privacy_chip_icon_padding_bottom);
            image.setLayoutParams(layoutParams);
            image.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
            mIconsContainer.addView(image);
        });
    }
}
+0 −62
Original line number Diff line number Diff line
/*
 * 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.systemui.statusbar.car.privacy;

import android.car.userlib.CarUserManagerHelper;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.util.Log;

/**
 * Class to hold the data for the applications that are using the AppOps permissions.
 */
public class PrivacyApplication {
    private static final String TAG = "PrivacyApplication";

    private Drawable mIcon;
    private String mApplicationName;

    public PrivacyApplication(String packageName, Context context) {
        try {
            CarUserManagerHelper carUserManagerHelper = new CarUserManagerHelper(context);
            ApplicationInfo app = context.getPackageManager()
                    .getApplicationInfoAsUser(packageName, 0,
                            carUserManagerHelper.getCurrentForegroundUserId());
            mIcon = context.getPackageManager().getApplicationIcon(app);
            mApplicationName = context.getPackageManager().getApplicationLabel(app).toString();
        } catch (PackageManager.NameNotFoundException e) {
            mApplicationName = packageName;
            Log.e(TAG, "Failed to to find package name", e);
        }
    }

    /**
     * Gets the application name.
     */
    public Drawable getIcon() {
        return mIcon;
    }

    /**
     * Gets the application name.
     */
    public String getApplicationName() {
        return mApplicationName;
    }
}
Loading