1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 *      http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14package com.android.settings.display;
15
16import android.content.Context;
17import android.os.IBinder;
18import android.os.Parcel;
19import android.os.RemoteException;
20import android.os.ServiceManager;
21import android.util.Log;
22
23import com.android.internal.annotations.VisibleForTesting;
24import com.android.internal.app.ColorDisplayController;
25import com.android.settings.R;
26import com.android.settings.core.BasePreferenceController;
27
28public class ColorModePreferenceController extends BasePreferenceController {
29    private static final String TAG = "ColorModePreference";
30    private static final String KEY_COLOR_MODE = "color_mode";
31
32    private static final int SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR = 1024;
33
34    private final ConfigurationWrapper mConfigWrapper;
35    private ColorDisplayController mColorDisplayController;
36
37    public ColorModePreferenceController(Context context) {
38        super(context, KEY_COLOR_MODE);
39        mConfigWrapper = new ConfigurationWrapper();
40    }
41
42    @Override
43    public int getAvailabilityStatus() {
44        return mConfigWrapper.isScreenWideColorGamut()
45                && !getColorDisplayController().getAccessibilityTransformActivated() ?
46                AVAILABLE : DISABLED_FOR_USER;
47    }
48
49    @Override
50    public CharSequence getSummary() {
51        final int colorMode = getColorDisplayController().getColorMode();
52        if (colorMode == ColorDisplayController.COLOR_MODE_AUTOMATIC) {
53            return mContext.getText(R.string.color_mode_option_automatic);
54        }
55        if (colorMode == ColorDisplayController.COLOR_MODE_SATURATED) {
56            return mContext.getText(R.string.color_mode_option_saturated);
57        }
58        if (colorMode == ColorDisplayController.COLOR_MODE_BOOSTED) {
59            return mContext.getText(R.string.color_mode_option_boosted);
60        }
61        return mContext.getText(R.string.color_mode_option_natural);
62    }
63
64    @VisibleForTesting
65    ColorDisplayController getColorDisplayController() {
66        if (mColorDisplayController == null) {
67            mColorDisplayController = new ColorDisplayController(mContext);
68        }
69        return mColorDisplayController;
70    }
71
72    @VisibleForTesting
73    static class ConfigurationWrapper {
74        private final IBinder mSurfaceFlinger;
75
76        ConfigurationWrapper() {
77            mSurfaceFlinger = ServiceManager.getService("SurfaceFlinger");
78        }
79
80        boolean isScreenWideColorGamut() {
81            if (mSurfaceFlinger != null) {
82                final Parcel data = Parcel.obtain();
83                final Parcel reply = Parcel.obtain();
84                data.writeInterfaceToken("android.ui.ISurfaceComposer");
85                try {
86                    mSurfaceFlinger.transact(SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR,
87                            data, reply, 0);
88                    return reply.readBoolean();
89                } catch (RemoteException ex) {
90                    Log.e(TAG, "Failed to query wide color support", ex);
91                } finally {
92                    data.recycle();
93                    reply.recycle();
94                }
95            }
96            return false;
97        }
98    }
99}
100