Home | History | Annotate | Download | only in development
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.development;
     18 
     19 import android.content.Context;
     20 import android.os.IBinder;
     21 import android.os.Parcel;
     22 import android.os.RemoteException;
     23 import android.os.ServiceManager;
     24 import android.support.annotation.VisibleForTesting;
     25 import android.support.v14.preference.SwitchPreference;
     26 import android.support.v7.preference.Preference;
     27 
     28 import com.android.settings.core.PreferenceControllerMixin;
     29 import com.android.settingslib.development.DeveloperOptionsPreferenceController;
     30 
     31 public class ShowSurfaceUpdatesPreferenceController extends DeveloperOptionsPreferenceController
     32         implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
     33 
     34     private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
     35 
     36     private static final int SETTING_VALUE_ON = 1;
     37     private static final int SETTING_VALUE_OFF = 0;
     38 
     39     @VisibleForTesting
     40     static final String SURFACE_FLINGER_SERVICE_KEY = "SurfaceFlinger";
     41     @VisibleForTesting
     42     static final int SURFACE_FLINGER_READ_CODE = 1010;
     43 
     44     private static final int SURFACE_FLINGER_WRITE_SURFACE_UPDATES_CODE = 1002;
     45     private static final String SURFACE_COMPOSER_INTERFACE_KEY = "android.ui.ISurfaceComposer";
     46 
     47     private final IBinder mSurfaceFlinger;
     48 
     49     public ShowSurfaceUpdatesPreferenceController(Context context) {
     50         super(context);
     51         mSurfaceFlinger = ServiceManager.getService(SURFACE_FLINGER_SERVICE_KEY);
     52     }
     53 
     54     @Override
     55     public String getPreferenceKey() {
     56         return SHOW_SCREEN_UPDATES_KEY;
     57     }
     58 
     59     @Override
     60     public boolean onPreferenceChange(Preference preference, Object newValue) {
     61         final boolean isEnabled = (Boolean) newValue;
     62         writeShowUpdatesSetting(isEnabled);
     63         return true;
     64     }
     65 
     66     @Override
     67     public void updateState(Preference preference) {
     68         updateShowUpdatesSetting();
     69     }
     70 
     71     @Override
     72     protected void onDeveloperOptionsSwitchDisabled() {
     73         super.onDeveloperOptionsSwitchDisabled();
     74         final SwitchPreference preference = (SwitchPreference) mPreference;
     75         if (preference.isChecked()) {
     76             // Writing false to the preference when the setting is already off will have a
     77             // side effect of turning on the preference that we wish to avoid
     78             writeShowUpdatesSetting(false);
     79             preference.setChecked(false);
     80         }
     81     }
     82 
     83     @VisibleForTesting
     84     void updateShowUpdatesSetting() {
     85         // magic communication with surface flinger.
     86         try {
     87             if (mSurfaceFlinger != null) {
     88                 final Parcel data = Parcel.obtain();
     89                 final Parcel reply = Parcel.obtain();
     90                 data.writeInterfaceToken(SURFACE_COMPOSER_INTERFACE_KEY);
     91                 mSurfaceFlinger.transact(SURFACE_FLINGER_READ_CODE, data, reply, 0 /* flags */);
     92                 @SuppressWarnings("unused") final int showCpu = reply.readInt();
     93                 @SuppressWarnings("unused") final int enableGL = reply.readInt();
     94                 final int showUpdates = reply.readInt();
     95                 ((SwitchPreference) mPreference).setChecked(showUpdates != SETTING_VALUE_OFF);
     96                 reply.recycle();
     97                 data.recycle();
     98             }
     99         } catch (RemoteException ex) {
    100             // intentional no-op
    101         }
    102     }
    103 
    104     @VisibleForTesting
    105     void writeShowUpdatesSetting(boolean isEnabled) {
    106         try {
    107             if (mSurfaceFlinger != null) {
    108                 final Parcel data = Parcel.obtain();
    109                 data.writeInterfaceToken(SURFACE_COMPOSER_INTERFACE_KEY);
    110                 final int showUpdates = isEnabled ? SETTING_VALUE_ON : SETTING_VALUE_OFF;
    111                 data.writeInt(showUpdates);
    112                 mSurfaceFlinger.transact(SURFACE_FLINGER_WRITE_SURFACE_UPDATES_CODE, data,
    113                         null /* reply */, 0 /* flags */);
    114                 data.recycle();
    115             }
    116         } catch (RemoteException ex) {
    117             // intentional no-op
    118         }
    119         updateShowUpdatesSetting();
    120     }
    121 }
    122