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

Commit fcf98251 authored by Felipe Leme's avatar Felipe Leme
Browse files

Updated privacy settings to launch custom content capture settings when available.

Test: manual verification
Test: atest EnableContentCapturePreferenceControllerTest \
      CtsContentTestCases:android.content.cts.AvailableIntentsTest#testRequestEnableContentCaptureIntent
Test: adb shell am start-activity -a android.settings.REQUEST_ENABLE_CONTENT_CAPTURE

Fixes: 119264902

Change-Id: I2a030c31d966d40feb6ba449e4bbc9ef8cf0565b
parent 08e2a5f0
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -63,12 +63,25 @@
        settings:searchable="false"/>

    <!-- Content Capture -->

    <!-- NOTE: content capture has a different preference, depending whether or not the
         ContentCaptureService implementations defines a custom settings activitiy on its manifest.
         Hence, we show both here, but the controller itself will decide if it's available or not.
    -->

    <SwitchPreference
        android:key="content_capture"
        android:title="@string/content_capture"
        android:summary="@string/content_capture_summary"
        settings:controller="com.android.settings.privacy.EnableContentCapturePreferenceController"/>

    <com.android.settings.widget.MasterSwitchPreference
        android:key="content_capture_custom_settings"
        android:title="@string/content_capture"
        android:summary="@string/content_capture_summary"
        settings:controller="com.android.settings.privacy.EnableContentCaptureWithServiceSettingsPreferenceController">
    </com.android.settings.widget.MasterSwitchPreference>

    <!-- Privacy Service -->
    <PreferenceCategory
        android:key="privacy_services"/>
+10 −19
Original line number Diff line number Diff line
@@ -16,43 +16,34 @@

package com.android.settings.privacy;

import android.annotation.NonNull;
import android.content.Context;
import android.os.IBinder;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.view.contentcapture.ContentCaptureManager;

import com.android.settings.core.TogglePreferenceController;
import com.android.settings.utils.ContentCaptureUtils;

public class EnableContentCapturePreferenceController extends TogglePreferenceController {
public final class EnableContentCapturePreferenceController extends TogglePreferenceController {

    private static final String KEY_SHOW_PASSWORD = "content_capture";
    private static final int MY_USER_ID = UserHandle.myUserId();

    public EnableContentCapturePreferenceController(Context context) {
        super(context, KEY_SHOW_PASSWORD);
    public EnableContentCapturePreferenceController(@NonNull Context context, @NonNull String key) {
        super(context, key);
    }

    @Override
    public boolean isChecked() {
        boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                Settings.Secure.CONTENT_CAPTURE_ENABLED, 1, MY_USER_ID) == 1;
        return enabled;
        return ContentCaptureUtils.isEnabledForUser(mContext);
    }

    @Override
    public boolean setChecked(boolean isChecked) {
        Settings.Secure.putIntForUser(mContext.getContentResolver(),
                Settings.Secure.CONTENT_CAPTURE_ENABLED, isChecked ? 1 : 0, MY_USER_ID);
        ContentCaptureUtils.setEnabledForUser(mContext, isChecked);
        return true;
    }

    @Override
    public int getAvailabilityStatus() {
        // We cannot look for ContentCaptureManager, because it's not available if the service
        // didn't whitelist Settings
        IBinder service = ServiceManager.checkService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
        return service != null ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
        boolean available = ContentCaptureUtils.isFeatureAvailable()
                && ContentCaptureUtils.getServiceSettingsComponentName() == null;
        return available ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
    }
}
+72 −0
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.settings.privacy;

import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import androidx.preference.Preference;

import com.android.settings.core.TogglePreferenceController;
import com.android.settings.utils.ContentCaptureUtils;
import com.android.settings.widget.MasterSwitchPreference;

public final class EnableContentCaptureWithServiceSettingsPreferenceController
        extends TogglePreferenceController {

    private static final String TAG = "ContentCaptureController";

    public EnableContentCaptureWithServiceSettingsPreferenceController(@NonNull Context context,
            @NonNull String key) {
        super(context, key);
    }

    @Override
    public boolean isChecked() {
        return ContentCaptureUtils.isEnabledForUser(mContext);
    }

    @Override
    public boolean setChecked(boolean isChecked) {
        ContentCaptureUtils.setEnabledForUser(mContext, isChecked);
        return true;
    }

    @Override
    public void updateState(Preference preference) {
        super.updateState(preference);

        ComponentName componentName = ContentCaptureUtils.getServiceSettingsComponentName();
        if (componentName != null) {
            preference.setIntent(new Intent(Intent.ACTION_MAIN).setComponent(componentName));
        } else {
            // Should not happen - preference should be disabled by controller
            Log.w(TAG, "No component name for custom service settings");
            preference.setSelectable(false);
        }
    }

    @Override
    public int getAvailabilityStatus() {
        boolean available = ContentCaptureUtils.isFeatureAvailable()
                && ContentCaptureUtils.getServiceSettingsComponentName() != null;
        return available ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
    }
}
+66 −0
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.settings.utils;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.os.IBinder;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.view.contentcapture.ContentCaptureManager;

public final class ContentCaptureUtils {

    private static final String TAG = ContentCaptureUtils.class.getSimpleName();
    private static final int MY_USER_ID = UserHandle.myUserId();

    public static boolean isEnabledForUser(@NonNull Context context) {
        boolean enabled = Settings.Secure.getIntForUser(context.getContentResolver(),
                Settings.Secure.CONTENT_CAPTURE_ENABLED, 1, MY_USER_ID) == 1;
        return enabled;
    }

    public static void setEnabledForUser(@NonNull Context context, boolean enabled) {
        Settings.Secure.putIntForUser(context.getContentResolver(),
                Settings.Secure.CONTENT_CAPTURE_ENABLED, enabled ? 1 : 0, MY_USER_ID);
    }

    public static boolean isFeatureAvailable() {
        // We cannot look for ContentCaptureManager, because it's not available if the service
        // didn't whitelist Settings
        IBinder service = ServiceManager.checkService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
        return service != null;
    }

    @Nullable
    public static ComponentName getServiceSettingsComponentName() {
        try {
            return ContentCaptureManager.getServiceSettingsComponentName();
        } catch (RuntimeException e) {
            Log.w(TAG, "Could not get service settings: " + e);
            return null;
        }
    }

    private ContentCaptureUtils() {
        throw new UnsupportedOperationException("contains only static methods");
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ public class EnableContentCapturePreferenceControllerTest {
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = RuntimeEnvironment.application;
        mController = new EnableContentCapturePreferenceController(mContext);
        mController = new EnableContentCapturePreferenceController(mContext, "THE_KEY_TO_SUCCESS");
        mPreference = new Preference(mContext);
        mPreference.setKey(mController.getPreferenceKey());
    }