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

Commit 98db0d13 authored by Roman Birg's avatar Roman Birg
Browse files

Torch: remind user flashlight is still on



Post a notification which informs the user the flashlight is still
enabled. But only do this when the user turns the screen off *while* the
flashlight is still on, so they see it next time they use the device.
Tapping on the notification will disable the flashlight.

Change-Id: I3689ff6498b97b813ccc10dc7dca3527fc8455aa
Signed-off-by: default avatarRoman Birg <roman@cyngn.com>
parent 9ec46da2
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2014 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="root"
    android:alpha="1.0"
    android:height="48dp"
    android:width="48dp"
    android:viewportHeight="48"
    android:viewportWidth="48" >
    <group
        android:name="ic_signal_flashlight"
        android:translateX="21.9995"
        android:translateY="25.73401" >
        <group
            android:name="ic_signal_flashlight_pivot"
            android:translateX="-23.21545"
            android:translateY="-18.86649" >
            <clip-path
                android:name="mask"
                android:pathData="M 37.8337860107,-39.2849731445 c 0.0,0.0 -35.8077850342,31.5523681641 -35.8077850342,31.5523681641 c 0.0,0.0 9.55097961426,9.55285644531 9.55097961426,9.55285644531 c 0.0,0.0 -2.61698913574,2.09387207031 -2.61698913574,2.09387207031 c 0.0,0.0 -9.75096130371,-9.56428527832 -9.75096130371,-9.56428527832 c 0.0,0.0 -34.6200408936,25.4699249268 -34.6200408936,25.4699249268 c 0.0,0.0 55.9664764404,69.742401123 55.9664764404,69.742401123 c 0.0,0.0 73.2448120117,-59.1047973633 73.2448120117,-59.1047973633 c 0.0,0.0 -55.9664916992,-69.7423400879 -55.9664916992,-69.7423400879 Z" />
            <group
                android:name="cross" >
                <path
                    android:name="cross_1"
                    android:pathData="M 8.34049987793,5.6930847168 c 0.0,0.0 0.274993896484,0.29997253418 0.274993896484,0.29997253418 "
                    android:strokeColor="#FFFFFFFF"
                    android:strokeAlpha="0"
                    android:strokeWidth="3.5"
                    android:fillColor="#00000000" />
            </group>
            <group
                android:name="flashlight"
                android:translateX="25.06235"
                android:translateY="22.48294" >
                <path
                    android:name="light"
                    android:pathData="M -9.40809631348,-23.6970062256 c 0.0,0.0 18.8699951172,0.0 18.8699951172,0.0 c 0.0,0.0 0.0,3.91700744629 0.0,3.91700744629 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,-3.91700744629 0.0,-3.91700744629 Z M 9.4615020752,-15.6629943848 c 0.0,0.0 0.0,-0.639999389648 0.0,-0.639999389649 c 0.0,0.0 -18.8699951172,0.0 -18.8699951172,0.0 c 0.0,0.0 0.0,0.639999389648 0.0,0.639999389649 c 0.0,0.0 -0.581008911133,5.18899536133 3.82598876953,7.52299499512 c 0.0,0.0 0.0,24.4429931641 0.0,24.4429931641 c 0.0,0.0 11.2129974365,0.0 11.2129974365,0.0 c 0.0,0.0 0.0,-24.4769897461 0.0,-24.4769897461 c 4.35900878906,-2.35301208496 3.83100891113,-7.48899841309 3.83100891113,-7.48899841309 Z M 0.0234985351562,0 c -1.52299499512,0 -2.75700378418,-1.23399353027 -2.75700378418,-2.75700378418 c 0.0,-1.52299499512 1.23400878906,-2.75700378418 2.75700378418,-2.75700378418 c 1.52299499512,0.0 2.75700378418,1.23400878906 2.75700378418,2.75700378418 c 0.0,1.52200317383 -1.23400878906,2.75700378418 -2.75700378418,2.75700378418 Z"
                    android:fillColor="#FFFFFFFF"
                    android:fillAlpha="1" />
            </group>
        </group>
    </group>
</vector>
+5 −0
Original line number Diff line number Diff line
@@ -335,4 +335,9 @@

    <!-- Notify user that they are in Lock-to-app (for devices without navbar) -->
    <string name="lock_to_app_toast_no_navbar">To unpin this screen, touch and hold the Back button.</string>

    <!-- Notification which notifies user flashlight is enabled -->
    <string name="quick_settings_tile_flashlight_not_title">Flashlight is on</string>
    <string name="quick_settings_tile_flashlight_not_summary">Tap to turn off</string>

</resources>
+5 −0
Original line number Diff line number Diff line
@@ -329,4 +329,9 @@
    <java-symbol type="array" name="config_packagesAllowedAccessToKillSwitch" />
    <java-symbol type="string" name="config_killSwitchLib" />
    <java-symbol type="string" name="config_killSwitchClass" />

    <!-- Flashlight notification -->
    <java-symbol type="string" name="quick_settings_tile_flashlight_not_title" />
    <java-symbol type="string" name="quick_settings_tile_flashlight_not_summary" />
    <java-symbol type="drawable" name="ic_signal_flashlight_disable" />
</resources>
+74 −0
Original line number Diff line number Diff line
@@ -16,7 +16,13 @@
package com.android.server;

import android.Manifest;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.hardware.ITorchCallback;
@@ -43,6 +49,8 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;

import com.android.internal.R;

import static android.os.Process.THREAD_PRIORITY_BACKGROUND;

/**
@@ -56,6 +64,9 @@ public class TorchService extends ITorchService.Stub {
    private static final int DISPATCH_STATE_CHANGE = 1;
    private static final int DISPATCH_AVAILABILITY_CHANGED = 2;

    private static final String ACTION_TURN_FLASHLIGHT_OFF =
            "com.android.server.TorchService.ACTION_TURN_FLASHLIGHT_OFF";

    private final Context mContext;

    private final SparseArray<CameraUserRecord> mCamerasInUse;
@@ -83,6 +94,18 @@ public class TorchService extends ITorchService.Stub {
    private SurfaceTexture mSurfaceTexture;
    private Surface mSurface;

    private boolean mReceiverRegistered;
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (ACTION_TURN_FLASHLIGHT_OFF.equals(intent.getAction())) {
                mHandler.post(mKillFlashlightRunnable);
            } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
                setNotificationShown(true);
            }
        }
    };

    private static class CameraUserRecord {
        IBinder token;
        int pid;
@@ -116,6 +139,54 @@ public class TorchService extends ITorchService.Stub {
        }
    }

    private void setNotificationShown(boolean show) {
        final long callingIdentity = Binder.clearCallingIdentity();
        try {
            NotificationManager nm = (NotificationManager)
                    mContext.getSystemService(Context.NOTIFICATION_SERVICE);
            if (show) {
                nm.notify(R.string.quick_settings_tile_flashlight_not_title, buildNotification());
            } else {
                nm.cancel(R.string.quick_settings_tile_flashlight_not_title);
            }
        } finally {
            Binder.restoreCallingIdentity(callingIdentity);
        }
    }

    private Notification buildNotification() {
        Intent fireMe = new Intent(ACTION_TURN_FLASHLIGHT_OFF);
        fireMe.setPackage(mContext.getPackageName());

        return new Notification.Builder(mContext)
                .setContentTitle(
                        mContext.getString(R.string.quick_settings_tile_flashlight_not_title))
                .setContentText(
                        mContext.getString(R.string.quick_settings_tile_flashlight_not_summary))
                .setAutoCancel(false)
                .setOngoing(true)
                .setVisibility(Notification.VISIBILITY_PUBLIC)
                .setSmallIcon(R.drawable.ic_signal_flashlight_disable)
                .setContentIntent(PendingIntent.getBroadcast(mContext, 0, fireMe, 0))
                .build();
    }

    private void setListenForScreenOff(boolean listen) {
        if (listen && !mReceiverRegistered) {
            IntentFilter filter = new IntentFilter();
            filter.addAction(ACTION_TURN_FLASHLIGHT_OFF);
            filter.addAction(Intent.ACTION_SCREEN_ON);
            mContext.registerReceiver(mReceiver, filter);
            mReceiverRegistered = true;
        } else if (!listen) {
            if (mReceiverRegistered) {
                mContext.unregisterReceiver(mReceiver);
                mReceiverRegistered = false;
            }
            setNotificationShown(false);
        }
    }

    @Override
    public void onCameraOpened(final IBinder token, final int cameraId) {
        if (DEBUG) Log.d(TAG, "onCameraOpened(token= " + token + ", cameraId=" + cameraId + ")");
@@ -172,8 +243,10 @@ public class TorchService extends ITorchService.Stub {
    public synchronized void setTorchEnabled(boolean enabled) {
        mContext.enforceCallingOrSelfPermission(
                Manifest.permission.ACCESS_TORCH_SERVICE, null);

        if (mTorchEnabled != enabled) {
            mTorchEnabled = enabled;
            setListenForScreenOff(enabled);
            postUpdateFlashlight();
        }
    }
@@ -347,6 +420,7 @@ public class TorchService extends ITorchService.Stub {
    }

    private void teardownTorch() {
        setListenForScreenOff(false);
        dispatchStateChange(false);
        if (mCameraDevice != null) {
            mCameraDevice.close();