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

Commit f5ce6209 authored by Yanli Wan's avatar Yanli Wan Committed by Android (Google) Code Review
Browse files

Merge "Start activity from Device Lock APEX if device is provisioned by Device Lock" into udc-dev

parents 6814775f ad151bf1
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -10158,7 +10158,9 @@
    <string name="financed_privacy_restrictions_removed">All restrictions are removed from the device</string>
    <!-- Label explaining that the app installed by credit provider can be uninstalled. [CHAR LIMIT=60]-->
    <string name="financed_privacy_uninstall_creditor_app">You can uninstall the creditor app</string>
    <!-- Title of setting on security settings screen on a device provisioned by Device Lock. This will take the user to a screen in Device Lock with information about what a device provider can control and their impact on the user's privacy. Shown on Device Lock provisioned devices only. [CHAR LIMIT=NONE] -->
    <!-- TODO(b/282040794): Update the title -->
    <string name="device_lock_info">Device Lock</string>
    <!-- Strings for displaying which applications were set as default for specific actions. -->
    <!-- Title for the apps that have been set as default handlers of camera-related intents. [CHAR LIMIT=30] -->
    <string name="default_camera_app_title">{count, plural,
+7 −0
Original line number Diff line number Diff line
@@ -146,6 +146,13 @@
            android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"
            settings:controller="com.android.settings.enterprise.FinancedPrivacyPreferenceController"/>

        <Preference
            android:key="device_lock_info"
            android:title="@string/device_lock_info"
            android:summary="@string/summary_placeholder"
            settings:controller="com.android.settings.devicelock.DeviceLockPreferenceController">
            <intent android:action="com.android.devicelockcontroller.action.DEVICE_INFO_SETTINGS"/>
        </Preference>
    </PreferenceCategory>

    <Preference
+7 −0
Original line number Diff line number Diff line
@@ -58,6 +58,13 @@
            android:fragment="com.android.settings.enterprise.EnterprisePrivacySettings"
            settings:controller="com.android.settings.enterprise.FinancedPrivacyPreferenceController"/>

        <Preference
            android:key="device_lock_info"
            android:title="@string/device_lock_info"
            android:summary="@string/summary_placeholder"
            settings:controller="com.android.settings.devicelock.DeviceLockPreferenceController">
            <intent android:action="com.android.devicelockcontroller.action.DEVICE_INFO_SETTINGS"/>
        </Preference>
    </PreferenceCategory>

    <Preference
+59 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.settings.devicelock;

import android.content.Context;
import android.devicelock.DeviceLockManager;
import android.util.Log;

import androidx.preference.Preference;

import com.android.settings.core.BasePreferenceController;

/**
 * The PreferenceController that manages the Device Lock entry preference.
 */
public final class DeviceLockPreferenceController extends BasePreferenceController {

    private static final String TAG = "DeviceLockPreferenceController";

    private final DeviceLockManager mDeviceLockManager;

    public DeviceLockPreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey);
        mDeviceLockManager = mContext.getSystemService(DeviceLockManager.class);
    }

    @Override
    public int getAvailabilityStatus() {
        // TODO(b/282856378): make this entry searchable
        return AVAILABLE_UNSEARCHABLE;
    }

    @Override
    public void updateState(Preference preference) {
        super.updateState(preference);
        mDeviceLockManager.getKioskApps(mContext.getMainExecutor(),
                result -> {
                    // if kiosk apps present on the device, the device is provisioned by Device Lock
                    boolean isDeviceProvisionedByDeviceLock = result != null && !result.isEmpty();
                    Log.d(TAG, "Set preference visibility to " + isDeviceProvisionedByDeviceLock);
                    // TODO(b/282179089): find alternatives instead of calling setVisible
                    preference.setVisible(isDeviceProvisionedByDeviceLock);
                });
    }
}
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.settings.devicelock;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.devicelock.DeviceLockManager;
import android.os.OutcomeReceiver;

import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;

import java.util.Collections;
import java.util.Map;

@RunWith(RobolectricTestRunner.class)
public final class DeviceLockPreferenceControllerTest {

    private static final String TEST_PREFERENCE_KEY = "KEY";
    private static final Map<Integer, String> TEST_KIOSK_APPS = Map.of(0, "test");
    @Mock
    private DeviceLockManager mDeviceLockManager;
    @Captor
    private ArgumentCaptor<OutcomeReceiver<Map<Integer, String>, Exception>>
            mOutcomeReceiverArgumentCaptor;
    private DeviceLockPreferenceController mController;
    private Context mContext;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = ApplicationProvider.getApplicationContext();
        Context context = spy(mContext);
        when(context.getSystemService(DeviceLockManager.class)).thenReturn(mDeviceLockManager);
        mController = new DeviceLockPreferenceController(context, TEST_PREFERENCE_KEY);
    }

    @Test
    public void testUpdateState_preferenceBecomesInvisibleIfNoKioskAppsPresent() {
        Preference preference = new Preference(mContext, null, 0, 0);
        preference.setVisible(true);

        mController.updateState(preference);

        verify(mDeviceLockManager).getKioskApps(any(), mOutcomeReceiverArgumentCaptor.capture());
        OutcomeReceiver<Map<Integer, String>, Exception> outcomeReceiver =
                mOutcomeReceiverArgumentCaptor.getValue();

        outcomeReceiver.onResult(Collections.emptyMap());
        assertThat(preference.isVisible()).isFalse();
    }

    @Test
    public void testUpdateState_preferenceBecomesVisibleIfKioskAppsPresent() {
        Preference preference = new Preference(mContext, null, 0, 0);
        preference.setVisible(false);

        mController.updateState(preference);

        verify(mDeviceLockManager).getKioskApps(any(), mOutcomeReceiverArgumentCaptor.capture());
        OutcomeReceiver<Map<Integer, String>, Exception> outcomeReceiver =
                mOutcomeReceiverArgumentCaptor.getValue();

        outcomeReceiver.onResult(TEST_KIOSK_APPS);
        assertThat(preference.isVisible()).isTrue();
    }
}